From 9e8720c2cac0ce03c6b2f51796f4dc6af461ccec Mon Sep 17 00:00:00 2001 From: Niklas Dewally Date: Wed, 29 Nov 2023 10:52:05 +0000 Subject: [PATCH 01/31] minion_rs: better callback example --- solvers/minion/src/lib.rs | 45 ++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/solvers/minion/src/lib.rs b/solvers/minion/src/lib.rs index 48889019a..b6f407e35 100644 --- a/solvers/minion/src/lib.rs +++ b/solvers/minion/src/lib.rs @@ -31,30 +31,14 @@ //! use std::collections::HashMap; //! //! // Get solutions out of Minion. -//! // In this example, we just check that the solutions are correct. -//! // See the documentation for Callback for more examples on how to use this. -//! -//! fn callback(solutions: HashMap) -> bool { -//! let x = match solutions.get("x").unwrap() { -//! Constant::Integer(n) => n, -//! _ => panic!("x should be a integer"), -//! }; -//! -//! let y = match solutions.get("y").unwrap() { -//! Constant::Integer(n) => n, -//! _ => panic!("y should be a integer"), -//! }; -//! -//! let z = match solutions.get("z").unwrap() { -//! Constant::Integer(n) => n, -//! _ => panic!("z should be a integer"), -//! }; -//! -//! assert_eq!(*x, 1); -//! assert_eq!(*y, 2); -//! assert_eq!(*z, 1); -//! -//! return true; +//! // See the documentation for Callback for details. +//! +//! static ALL_SOLUTIONS: Mutex>> = Mutex::new(vec![]); +//! +//! fn callback(solutions: HashMap) -> bool { +//! let mut guard = ALL_SOLUTIONS.lock().unwrap(); +//! guard.push(solutions); +//! true //! } //! //! // Build and run the model. @@ -99,6 +83,19 @@ //! //! let res = run_minion(model, callback); //! res.expect("Error occurred"); +//! +//! // Get solutions +//! let guard = ALL_SOLUTIONS.lock().unwrap(); +//! let solution_set_1 = &(guard.get(0).unwrap()); +//! +//! let x1 = solution_set_1.get("x").unwrap(); +//! let y1 = solution_set_1.get("y").unwrap(); +//! let z1 = solution_set_1.get("z").unwrap(); +//! +//! assert_eq!(guard.len(),1); +//! assert_eq!(*x1,Constant::Integer(1)); +//! assert_eq!(*y1,Constant::Integer(2)); +//! assert_eq!(*z1,Constant::Integer(1)); //! ``` //! //! ## `PRINT` and `VARORDER` From 92149b169fc61b2da876c477c6e5bbfc4fe54c3f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 08:55:55 +0000 Subject: [PATCH 02/31] Bump the all group with 2 updates Bumps the all group with 2 updates: [clap](https://github.com/clap-rs/clap) and [versions](https://github.com/fosskers/rs-versions). Updates `clap` from 4.4.10 to 4.4.11 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v4.4.10...v4.4.11) Updates `versions` from 5.0.1 to 6.0.0 - [Release notes](https://github.com/fosskers/rs-versions/releases) - [Changelog](https://github.com/fosskers/rs-versions/blob/master/CHANGELOG.md) - [Commits](https://github.com/fosskers/rs-versions/commits) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all - dependency-name: versions dependency-type: direct:production update-type: version-update:semver-major dependency-group: all ... Signed-off-by: dependabot[bot] --- Cargo.lock | 16 ++++++++-------- conjure_oxide/Cargo.toml | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 926561d42..71fe99186 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -214,9 +214,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.10" +version = "4.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fffed7514f420abec6d183b1d3acfd9099c79c3a10a06ade4f8203f1411272" +checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" dependencies = [ "clap_builder", "clap_derive", @@ -224,9 +224,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.9" +version = "4.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63361bae7eef3771745f02d8d892bec2fee5f6e34af316ba556e7f97a7069ff1" +checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" dependencies = [ "anstream", "anstyle", @@ -457,9 +457,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" dependencies = [ "either", ] @@ -886,9 +886,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "versions" -version = "5.0.1" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c73a36bc44e3039f51fbee93e39f41225f6b17b380eb70cc2aab942df06b34dd" +checksum = "d7c271c81503258e3850c9d0f0d279d4ce9458d3388ef9eaa081b10d542182c3" dependencies = [ "itertools", "nom", diff --git a/conjure_oxide/Cargo.toml b/conjure_oxide/Cargo.toml index b52747e28..ea973dd48 100644 --- a/conjure_oxide/Cargo.toml +++ b/conjure_oxide/Cargo.toml @@ -15,10 +15,10 @@ serde_with = "3.4.0" thiserror = "1.0.50" minion_rs = {path = "../solvers/minion" } anyhow = "1.0.75" -clap = { version = "4.4.10", features = ["derive"] } +clap = { version = "4.4.11", features = ["derive"] } strum_macros = "0.25.3" strum = "0.25.0" -versions = "5.0.1" +versions = "6.0.0" [lints] workspace = true From b7ddf4a3148e874bd266ca6fe0e32caa5d38bed0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 08:41:01 +0000 Subject: [PATCH 03/31] Bump the all group with 1 update Bumps the all group with 1 update: [thiserror](https://github.com/dtolnay/thiserror). - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/1.0.50...1.0.51) --- updated-dependencies: - dependency-name: thiserror dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- conjure_oxide/Cargo.toml | 2 +- solvers/minion/Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 71fe99186..56f0cd615 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -825,18 +825,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df" dependencies = [ "proc-macro2", "quote", diff --git a/conjure_oxide/Cargo.toml b/conjure_oxide/Cargo.toml index ea973dd48..476105cdb 100644 --- a/conjure_oxide/Cargo.toml +++ b/conjure_oxide/Cargo.toml @@ -12,7 +12,7 @@ walkdir = "2.4.0" serde = { version = "1.0.192", features = ["derive"] } serde_json = "1.0.108" serde_with = "3.4.0" -thiserror = "1.0.50" +thiserror = "1.0.51" minion_rs = {path = "../solvers/minion" } anyhow = "1.0.75" clap = { version = "4.4.11", features = ["derive"] } diff --git a/solvers/minion/Cargo.toml b/solvers/minion/Cargo.toml index d814f97de..2de1be3c1 100644 --- a/solvers/minion/Cargo.toml +++ b/solvers/minion/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] anyhow = "1.0.75" -thiserror = "1.0.50" +thiserror = "1.0.51" [build-dependencies] bindgen = "0.69.1" From ddf5a0c5f5ee0429db5104c7d1b312a1f5524a8e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 08:27:45 +0000 Subject: [PATCH 04/31] Bump the pip-essence-feature-usage-stats group Bumps the pip-essence-feature-usage-stats group in /tools/essence-feature-usage-stats with 4 updates: [black](https://github.com/psf/black), [pathspec](https://github.com/cpburnz/python-pathspec), [platformdirs](https://github.com/platformdirs/platformdirs) and [ruff](https://github.com/astral-sh/ruff). Updates `black` from 23.11.0 to 23.12.1 - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/23.11.0...23.12.1) Updates `pathspec` from 0.11.2 to 0.12.1 - [Release notes](https://github.com/cpburnz/python-pathspec/releases) - [Changelog](https://github.com/cpburnz/python-pathspec/blob/master/CHANGES.rst) - [Commits](https://github.com/cpburnz/python-pathspec/compare/v0.11.2...v0.12.1) Updates `platformdirs` from 4.0.0 to 4.1.0 - [Release notes](https://github.com/platformdirs/platformdirs/releases) - [Changelog](https://github.com/platformdirs/platformdirs/blob/main/CHANGES.rst) - [Commits](https://github.com/platformdirs/platformdirs/compare/4.0.0...4.1.0) Updates `ruff` from 0.1.6 to 0.1.9 - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.1.6...v0.1.9) --- updated-dependencies: - dependency-name: black dependency-type: direct:production update-type: version-update:semver-minor dependency-group: pip-essence-feature-usage-stats - dependency-name: pathspec dependency-type: direct:production update-type: version-update:semver-minor dependency-group: pip-essence-feature-usage-stats - dependency-name: platformdirs dependency-type: direct:production update-type: version-update:semver-minor dependency-group: pip-essence-feature-usage-stats - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch dependency-group: pip-essence-feature-usage-stats ... Signed-off-by: dependabot[bot] --- tools/essence-feature-usage-stats/requirements.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/essence-feature-usage-stats/requirements.txt b/tools/essence-feature-usage-stats/requirements.txt index d86bfe552..4e38124fd 100644 --- a/tools/essence-feature-usage-stats/requirements.txt +++ b/tools/essence-feature-usage-stats/requirements.txt @@ -1,4 +1,4 @@ -black==23.11.0 +black==23.12.1 certifi==2023.11.17 charset-normalizer==3.3.2 click==8.1.7 @@ -9,11 +9,11 @@ Jinja2==3.1.2 MarkupSafe==2.1.3 mypy-extensions==1.0.0 packaging==23.2 -pathspec==0.11.2 -platformdirs==4.0.0 +pathspec==0.12.1 +platformdirs==4.1.0 python-dotenv==1.0.0 requests==2.31.0 -ruff==0.1.6 +ruff==0.1.9 smmap==5.0.1 tqdm==4.66.1 urllib3==2.1.0 From 54323ea4710c57f8be7c785ec1ae9926e821de4f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 08:29:33 +0000 Subject: [PATCH 05/31] Bump the all group with 4 updates Bumps the all group with 4 updates: [serde_json](https://github.com/serde-rs/json), [thiserror](https://github.com/dtolnay/thiserror), [anyhow](https://github.com/dtolnay/anyhow) and [clap](https://github.com/clap-rs/clap). Updates `serde_json` from 1.0.108 to 1.0.109 - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.108...v1.0.109) Updates `thiserror` from 1.0.51 to 1.0.53 - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/1.0.51...1.0.53) Updates `anyhow` from 1.0.75 to 1.0.78 - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.75...1.0.78) Updates `clap` from 4.4.11 to 4.4.12 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v4.4.11...v4.4.12) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all - dependency-name: thiserror dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all ... Signed-off-by: dependabot[bot] --- Cargo.lock | 24 ++++++++++++------------ conjure_oxide/Cargo.toml | 8 ++++---- solvers/minion/Cargo.toml | 4 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 56f0cd615..841e47f0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -76,9 +76,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "ca87830a3e3fb156dc96cfbd31cb620265dd053be734723f22b760d6cc3c3051" [[package]] name = "autocfg" @@ -214,9 +214,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.11" +version = "4.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" +checksum = "dcfab8ba68f3668e89f6ff60f5b205cea56aa7b769451a59f34b8682f51c056d" dependencies = [ "clap_builder", "clap_derive", @@ -224,9 +224,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.11" +version = "4.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" +checksum = "fb7fb5e4e979aec3be7791562fcba452f94ad85e954da024396433e0e25a79e9" dependencies = [ "anstream", "anstyle", @@ -732,9 +732,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "cb0652c533506ad7a2e353cce269330d6afd8bdfb6d75e0ace5b35aacbd7b9e9" dependencies = [ "itoa", "ryu", @@ -825,18 +825,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.51" +version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7" +checksum = "b2cd5904763bad08ad5513ddbb12cf2ae273ca53fa9f68e843e236ec6dfccc09" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.51" +version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df" +checksum = "3dcf4a824cce0aeacd6f38ae6f24234c8e80d68632338ebaa1443b5df9e29e19" dependencies = [ "proc-macro2", "quote", diff --git a/conjure_oxide/Cargo.toml b/conjure_oxide/Cargo.toml index 476105cdb..9c66f1996 100644 --- a/conjure_oxide/Cargo.toml +++ b/conjure_oxide/Cargo.toml @@ -10,12 +10,12 @@ walkdir = "2.4.0" [dependencies] serde = { version = "1.0.192", features = ["derive"] } -serde_json = "1.0.108" +serde_json = "1.0.109" serde_with = "3.4.0" -thiserror = "1.0.51" +thiserror = "1.0.53" minion_rs = {path = "../solvers/minion" } -anyhow = "1.0.75" -clap = { version = "4.4.11", features = ["derive"] } +anyhow = "1.0.78" +clap = { version = "4.4.12", features = ["derive"] } strum_macros = "0.25.3" strum = "0.25.0" versions = "6.0.0" diff --git a/solvers/minion/Cargo.toml b/solvers/minion/Cargo.toml index 2de1be3c1..64ec8318f 100644 --- a/solvers/minion/Cargo.toml +++ b/solvers/minion/Cargo.toml @@ -6,8 +6,8 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -anyhow = "1.0.75" -thiserror = "1.0.51" +anyhow = "1.0.78" +thiserror = "1.0.53" [build-dependencies] bindgen = "0.69.1" From 9987d06045be690d25f4016f1bdd35317b2a3fac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 08:31:57 +0000 Subject: [PATCH 06/31] Bump the all group with 5 updates Bumps the all group with 5 updates: | Package | From | To | | --- | --- | --- | | [serde](https://github.com/serde-rs/serde) | `1.0.193` | `1.0.195` | | [serde_json](https://github.com/serde-rs/json) | `1.0.109` | `1.0.111` | | [thiserror](https://github.com/dtolnay/thiserror) | `1.0.53` | `1.0.56` | | [anyhow](https://github.com/dtolnay/anyhow) | `1.0.78` | `1.0.79` | | [clap](https://github.com/clap-rs/clap) | `4.4.12` | `4.4.13` | Updates `serde` from 1.0.193 to 1.0.195 - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.193...v1.0.195) Updates `serde_json` from 1.0.109 to 1.0.111 - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.109...v1.0.111) Updates `thiserror` from 1.0.53 to 1.0.56 - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/1.0.53...1.0.56) Updates `anyhow` from 1.0.78 to 1.0.79 - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.78...1.0.79) Updates `clap` from 4.4.12 to 4.4.13 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v4.4.12...v4.4.13) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all - dependency-name: thiserror dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all ... Signed-off-by: dependabot[bot] --- Cargo.lock | 62 +++++++++++++++++++-------------------- conjure_oxide/Cargo.toml | 10 +++---- solvers/minion/Cargo.toml | 4 +-- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 841e47f0a..c6d3ae6fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -76,9 +76,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca87830a3e3fb156dc96cfbd31cb620265dd053be734723f22b760d6cc3c3051" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "autocfg" @@ -133,7 +133,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.39", + "syn 2.0.48", "which", ] @@ -214,9 +214,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.12" +version = "4.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfab8ba68f3668e89f6ff60f5b205cea56aa7b769451a59f34b8682f51c056d" +checksum = "52bdc885e4cacc7f7c9eedc1ef6da641603180c783c41a15c264944deeaab642" dependencies = [ "clap_builder", "clap_derive", @@ -243,7 +243,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -302,7 +302,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -313,7 +313,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -620,23 +620,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -712,29 +712,29 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.193" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] name = "serde_json" -version = "1.0.109" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0652c533506ad7a2e353cce269330d6afd8bdfb6d75e0ace5b35aacbd7b9e9" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" dependencies = [ "itoa", "ryu", @@ -767,7 +767,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -798,7 +798,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -814,9 +814,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -825,22 +825,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.53" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2cd5904763bad08ad5513ddbb12cf2ae273ca53fa9f68e843e236ec6dfccc09" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.53" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcf4a824cce0aeacd6f38ae6f24234c8e80d68632338ebaa1443b5df9e29e19" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -925,7 +925,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", "wasm-bindgen-shared", ] @@ -947,7 +947,7 @@ checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/conjure_oxide/Cargo.toml b/conjure_oxide/Cargo.toml index 9c66f1996..7cd18c40b 100644 --- a/conjure_oxide/Cargo.toml +++ b/conjure_oxide/Cargo.toml @@ -9,13 +9,13 @@ default-run = "conjure_oxide" walkdir = "2.4.0" [dependencies] -serde = { version = "1.0.192", features = ["derive"] } -serde_json = "1.0.109" +serde = { version = "1.0.195", features = ["derive"] } +serde_json = "1.0.111" serde_with = "3.4.0" -thiserror = "1.0.53" +thiserror = "1.0.56" minion_rs = {path = "../solvers/minion" } -anyhow = "1.0.78" -clap = { version = "4.4.12", features = ["derive"] } +anyhow = "1.0.79" +clap = { version = "4.4.13", features = ["derive"] } strum_macros = "0.25.3" strum = "0.25.0" versions = "6.0.0" diff --git a/solvers/minion/Cargo.toml b/solvers/minion/Cargo.toml index 64ec8318f..208446dc7 100644 --- a/solvers/minion/Cargo.toml +++ b/solvers/minion/Cargo.toml @@ -6,8 +6,8 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -anyhow = "1.0.78" -thiserror = "1.0.53" +anyhow = "1.0.79" +thiserror = "1.0.56" [build-dependencies] bindgen = "0.69.1" From 8b75bd2a65c5e4806e078170f5f585274faaabaa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 17:10:31 +0000 Subject: [PATCH 07/31] Bump gitpython in /tools/essence-feature-usage-stats Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.1.40 to 3.1.41. - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES) - [Commits](https://github.com/gitpython-developers/GitPython/compare/3.1.40...3.1.41) --- updated-dependencies: - dependency-name: gitpython dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- tools/essence-feature-usage-stats/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/essence-feature-usage-stats/requirements.txt b/tools/essence-feature-usage-stats/requirements.txt index 4e38124fd..ae0c5336f 100644 --- a/tools/essence-feature-usage-stats/requirements.txt +++ b/tools/essence-feature-usage-stats/requirements.txt @@ -3,7 +3,7 @@ certifi==2023.11.17 charset-normalizer==3.3.2 click==8.1.7 gitdb==4.0.11 -GitPython==3.1.40 +GitPython==3.1.41 idna==3.6 Jinja2==3.1.2 MarkupSafe==2.1.3 From b52e3f87191bc4f88813202993fcb82f7eb8a3f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 21:43:51 +0000 Subject: [PATCH 08/31] Bump jinja2 from 3.1.2 to 3.1.3 in /tools/essence-feature-usage-stats Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.2 to 3.1.3. - [Release notes](https://github.com/pallets/jinja/releases) - [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/jinja/compare/3.1.2...3.1.3) --- updated-dependencies: - dependency-name: jinja2 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- tools/essence-feature-usage-stats/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/essence-feature-usage-stats/requirements.txt b/tools/essence-feature-usage-stats/requirements.txt index ae0c5336f..ba2dcee4b 100644 --- a/tools/essence-feature-usage-stats/requirements.txt +++ b/tools/essence-feature-usage-stats/requirements.txt @@ -5,7 +5,7 @@ click==8.1.7 gitdb==4.0.11 GitPython==3.1.41 idna==3.6 -Jinja2==3.1.2 +Jinja2==3.1.3 MarkupSafe==2.1.3 mypy-extensions==1.0.0 packaging==23.2 From 8369208bd1f9b20393ce35d09605c007ea5afc70 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 08:36:37 +0000 Subject: [PATCH 09/31] Bump the all group with 3 updates Bumps the all group with 3 updates: [clap](https://github.com/clap-rs/clap), [versions](https://github.com/fosskers/rs-versions) and [bindgen](https://github.com/rust-lang/rust-bindgen). Updates `clap` from 4.4.13 to 4.4.16 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v4.4.13...v4.4.16) Updates `versions` from 6.0.0 to 6.1.0 - [Release notes](https://github.com/fosskers/rs-versions/releases) - [Changelog](https://github.com/fosskers/rs-versions/blob/master/CHANGELOG.md) - [Commits](https://github.com/fosskers/rs-versions/compare/v6.0.0...v6.1.0) Updates `bindgen` from 0.69.1 to 0.69.2 - [Release notes](https://github.com/rust-lang/rust-bindgen/releases) - [Changelog](https://github.com/rust-lang/rust-bindgen/blob/main/CHANGELOG.md) - [Commits](https://github.com/rust-lang/rust-bindgen/compare/v0.69.1...v0.69.2) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all - dependency-name: versions dependency-type: direct:production update-type: version-update:semver-minor dependency-group: all - dependency-name: bindgen dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all ... Signed-off-by: dependabot[bot] --- Cargo.lock | 24 ++++++++++++------------ conjure_oxide/Cargo.toml | 4 ++-- solvers/chuffed/Cargo.toml | 2 +- solvers/minion/Cargo.toml | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c6d3ae6fc..ceb82d034 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "4cd2405b3ac1faab2990b74d728624cd9fd115651fcecc7c2d8daf01376275ba" dependencies = [ "anstyle", "anstyle-parse", @@ -116,9 +116,9 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.69.1" +version = "0.69.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ffcebc3849946a7170a05992aac39da343a90676ab392c51a4280981d6379c2" +checksum = "a4c69fae65a523209d34240b60abe0c42d33d1045d445c0839d8a4894a736e2d" dependencies = [ "bitflags 2.4.1", "cexpr", @@ -197,7 +197,7 @@ dependencies = [ name = "chuffed_rs" version = "0.1.0" dependencies = [ - "bindgen 0.69.1", + "bindgen 0.69.2", "cc", ] @@ -214,9 +214,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.13" +version = "4.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52bdc885e4cacc7f7c9eedc1ef6da641603180c783c41a15c264944deeaab642" +checksum = "58e54881c004cec7895b0068a0a954cd5d62da01aef83fa35b1e594497bf5445" dependencies = [ "clap_builder", "clap_derive", @@ -224,9 +224,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.12" +version = "4.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb7fb5e4e979aec3be7791562fcba452f94ad85e954da024396433e0e25a79e9" +checksum = "59cb82d7f531603d2fd1f507441cdd35184fa81beff7bd489570de7f773460bb" dependencies = [ "anstream", "anstyle", @@ -571,7 +571,7 @@ name = "minion_rs" version = "0.0.1" dependencies = [ "anyhow", - "bindgen 0.69.1", + "bindgen 0.69.2", "glob", "thiserror", ] @@ -886,9 +886,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "versions" -version = "6.0.0" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c271c81503258e3850c9d0f0d279d4ce9458d3388ef9eaa081b10d542182c3" +checksum = "f37ff4899935ba747849dd9eeb27c0bdd0da0210236704b7e4681a6c7bd6f9c6" dependencies = [ "itertools", "nom", diff --git a/conjure_oxide/Cargo.toml b/conjure_oxide/Cargo.toml index 7cd18c40b..4cc454eb1 100644 --- a/conjure_oxide/Cargo.toml +++ b/conjure_oxide/Cargo.toml @@ -15,10 +15,10 @@ serde_with = "3.4.0" thiserror = "1.0.56" minion_rs = {path = "../solvers/minion" } anyhow = "1.0.79" -clap = { version = "4.4.13", features = ["derive"] } +clap = { version = "4.4.16", features = ["derive"] } strum_macros = "0.25.3" strum = "0.25.0" -versions = "6.0.0" +versions = "6.1.0" [lints] workspace = true diff --git a/solvers/chuffed/Cargo.toml b/solvers/chuffed/Cargo.toml index 0f3b4a50d..2ccc9b0c8 100644 --- a/solvers/chuffed/Cargo.toml +++ b/solvers/chuffed/Cargo.toml @@ -10,4 +10,4 @@ edition = "2021" [build-dependencies] cc = { version = "1.0.83", features = ["parallel"] } -bindgen = "0.69.1" +bindgen = "0.69.2" diff --git a/solvers/minion/Cargo.toml b/solvers/minion/Cargo.toml index 208446dc7..226de0a7c 100644 --- a/solvers/minion/Cargo.toml +++ b/solvers/minion/Cargo.toml @@ -10,7 +10,7 @@ anyhow = "1.0.79" thiserror = "1.0.56" [build-dependencies] -bindgen = "0.69.1" +bindgen = "0.69.2" glob = "0.3.1" [lints.clippy] From e86f7b2353bb34e3215cda78f7898f26f019ae40 Mon Sep 17 00:00:00 2001 From: Felix Date: Tue, 28 Nov 2023 16:00:12 +0000 Subject: [PATCH 10/31] Refactor central ADTs into a core module for modularity This is a refactor in preparation for adding procedural macros in https://github.com/conjure-cp/conjure-oxide/pull/112 Crates that define proc macros can only export proc macros. Therefore, these must be a seperate crate than Conjure Oxide (Conjure Macros). To avoid circular dependencies, datatypes previously defined in Conjure Oxide that are also needed in Conjure Macros have been refactored into a Conjure Core Crate. This creates the following dependency graph: Conjure Core -----> Conjure Macros | | | v ------------------> Conjure Oxide Conjure Oxide will still be the sole "user interface", and will re-export members of core and macros when these should be public facing. Co-authored-by: Niklas Dewally --- .vscode/settings.json | 5 +++-- Cargo.lock | 13 +++++++++++++ Cargo.toml | 1 + conjure_oxide/Cargo.toml | 2 ++ conjure_oxide/src/lib.rs | 6 ++++-- conjure_oxide/src/main.rs | 9 +++++++-- conjure_oxide/src/parse.rs | 8 +------- conjure_oxide/src/solvers/error.rs | 3 +-- conjure_oxide/src/solvers/minion.rs | 15 ++++++--------- conjure_oxide/src/solvers/mod.rs | 10 ++++++++-- conjure_oxide/tests/generated_tests.rs | 3 ++- crates/conjure_core/Cargo.toml | 15 +++++++++++++++ crates/conjure_core/README.md | 4 ++++ {conjure_oxide => crates/conjure_core}/src/ast.rs | 0 crates/conjure_core/src/lib.rs | 4 ++++ .../conjure_core/src/solvers.rs | 0 16 files changed, 71 insertions(+), 27 deletions(-) create mode 100644 crates/conjure_core/Cargo.toml create mode 100644 crates/conjure_core/README.md rename {conjure_oxide => crates/conjure_core}/src/ast.rs (100%) create mode 100644 crates/conjure_core/src/lib.rs rename conjure_oxide/src/solvers/solver_list.rs => crates/conjure_core/src/solvers.rs (100%) diff --git a/.vscode/settings.json b/.vscode/settings.json index 03de4a74d..cf916d511 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,5 @@ -"rust": { +{ + "rust-analyzer.check.command": "check", "editor.defaultFormatter": "rust-lang.rust-analyzer", - "editor.formatOnSave": true + "editor.formatOnSave": true, } diff --git a/Cargo.lock b/Cargo.lock index ceb82d034..b13643407 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -258,12 +258,25 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "conjure_core" +version = "0.0.1" +dependencies = [ + "serde", + "serde_json", + "serde_with", + "strum", + "strum_macros", + "thiserror", +] + [[package]] name = "conjure_oxide" version = "0.0.1" dependencies = [ "anyhow", "clap", + "conjure_core", "minion_rs", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index a195dc458..834320ce1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ resolver = "2" members = [ "conjure_oxide", + "crates/conjure_core", "solvers/kissat", "solvers/minion", "solvers/chuffed", diff --git a/conjure_oxide/Cargo.toml b/conjure_oxide/Cargo.toml index 4cc454eb1..7015b3012 100644 --- a/conjure_oxide/Cargo.toml +++ b/conjure_oxide/Cargo.toml @@ -9,6 +9,8 @@ default-run = "conjure_oxide" walkdir = "2.4.0" [dependencies] +conjure_core = {path = "../crates/conjure_core" } + serde = { version = "1.0.195", features = ["derive"] } serde_json = "1.0.111" serde_with = "3.4.0" diff --git a/conjure_oxide/src/lib.rs b/conjure_oxide/src/lib.rs index 747851612..c2c17a283 100644 --- a/conjure_oxide/src/lib.rs +++ b/conjure_oxide/src/lib.rs @@ -1,8 +1,10 @@ -pub mod ast; pub mod error; pub mod find_conjure; pub mod parse; mod solvers; -pub use ast::Model; +pub use conjure_core::ast; // re-export core::ast as conjure_oxide::ast +pub use conjure_core::ast::Model; // rexport core::ast::Model as conjure_oxide::Model +pub use conjure_core::solvers::Solver; + pub use error::Error; diff --git a/conjure_oxide/src/main.rs b/conjure_oxide/src/main.rs index f60496bc4..6452d82a9 100644 --- a/conjure_oxide/src/main.rs +++ b/conjure_oxide/src/main.rs @@ -6,7 +6,7 @@ use std::path::PathBuf; use anyhow::Result as AnyhowResult; use clap::{arg, command, Parser}; use conjure_oxide::find_conjure::conjure_executable; -use conjure_oxide::parse::parse_json; +use conjure_oxide::parse::model_from_json; #[derive(Parser)] #[command(author, version, about, long_about = None)] @@ -45,7 +45,12 @@ pub fn main() -> AnyhowResult<()> { let astjson = String::from_utf8(output.stdout)?; - let model = parse_json(&astjson)?; + let model = model_from_json(&astjson)?; println!("{:?}", model); + + // for rule in get_rules_by_kind() { + // println!("Applying rule {:?}", rule); + // } + Ok(()) } diff --git a/conjure_oxide/src/parse.rs b/conjure_oxide/src/parse.rs index 0bfc7bcfd..fc9b4cf82 100644 --- a/conjure_oxide/src/parse.rs +++ b/conjure_oxide/src/parse.rs @@ -6,7 +6,7 @@ use crate::ast::{DecisionVariable, Domain, Expression, Model, Name, Range}; use crate::error::{Error, Result}; use serde_json::Value as JsonValue; -pub fn parse_json(str: &str) -> Result { +pub fn model_from_json(str: &str) -> Result { let mut m = Model::new(); let v: JsonValue = serde_json::from_str(str)?; let statements = v["mStatements"] @@ -217,9 +217,3 @@ fn parse_constant(constant: &serde_json::Map) -> Option panic!("Unhandled parse_constant {:#?}", otherwise), } } - -impl Model { - pub fn from_json(str: &str) -> Result { - parse_json(str) - } -} diff --git a/conjure_oxide/src/solvers/error.rs b/conjure_oxide/src/solvers/error.rs index b080a4acf..701816c1d 100644 --- a/conjure_oxide/src/solvers/error.rs +++ b/conjure_oxide/src/solvers/error.rs @@ -1,7 +1,6 @@ +use crate::Solver; use thiserror::Error; -use super::Solver; - #[derive(Error, Debug)] pub enum SolverError { #[error("not supported in solver `{0}`: `{1}`.")] diff --git a/conjure_oxide/src/solvers/minion.rs b/conjure_oxide/src/solvers/minion.rs index 9e2f43db5..f3eea6095 100644 --- a/conjure_oxide/src/solvers/minion.rs +++ b/conjure_oxide/src/solvers/minion.rs @@ -1,7 +1,7 @@ //! Solver interface to minion_rs. -#[allow(unused_imports)] -use anyhow::anyhow; +use super::{FromConjureModel, SolverError}; +use crate::Solver; use crate::ast::{ DecisionVariable, Domain as ConjureDomain, Expression as ConjureExpression, @@ -12,14 +12,10 @@ use minion_rs::ast::{ Var as MinionVar, VarDomain as MinionDomain, }; -use super::{Solver, SolverError}; - const SOLVER: Solver = Solver::Minion; -impl TryFrom for MinionModel { - type Error = SolverError; - - fn try_from(conjure_model: ConjureModel) -> Result { +impl FromConjureModel for MinionModel { + fn from_conjure(conjure_model: ConjureModel) -> Result { let mut minion_model = MinionModel::new(); // We assume (for now) that the conjure model is fully valid @@ -211,6 +207,7 @@ fn name_to_string(name: ConjureName) -> String { #[cfg(test)] mod tests { + use anyhow::anyhow; use std::collections::HashMap; use minion_rs::ast::VarName; @@ -248,7 +245,7 @@ mod tests { model.constraints.push(leq); model.constraints.push(ineq); - let minion_model = MinionModel::try_from(model)?; + let minion_model = MinionModel::from_conjure(model)?; Ok(minion_rs::run_minion(minion_model, xyz_callback)?) } diff --git a/conjure_oxide/src/solvers/mod.rs b/conjure_oxide/src/solvers/mod.rs index 733306ab9..55bbf4aa8 100644 --- a/conjure_oxide/src/solvers/mod.rs +++ b/conjure_oxide/src/solvers/mod.rs @@ -1,5 +1,11 @@ mod error; pub mod minion; +pub use crate::ast::Model; pub use error::*; -mod solver_list; -pub use solver_list::*; + +pub trait FromConjureModel +where + Self: Sized, +{ + fn from_conjure(model: Model) -> Result; +} diff --git a/conjure_oxide/tests/generated_tests.rs b/conjure_oxide/tests/generated_tests.rs index b25af0e65..c925ef4ec 100644 --- a/conjure_oxide/tests/generated_tests.rs +++ b/conjure_oxide/tests/generated_tests.rs @@ -1,4 +1,5 @@ use conjure_oxide::ast::Model; +use conjure_oxide::parse::model_from_json; use serde_json::Value; use std::env; use std::error::Error; @@ -37,7 +38,7 @@ fn integration_test(path: &str, essence_base: &str) -> Result<(), Box let astjson = String::from_utf8(output.stdout)?; // "parsing" astjson as Model - let generated_mdl = Model::from_json(&astjson)?; + let generated_mdl = model_from_json(&astjson)?; // a consistent sorting of the keys of json objects // only required for the generated version diff --git a/crates/conjure_core/Cargo.toml b/crates/conjure_core/Cargo.toml new file mode 100644 index 000000000..bc4f96610 --- /dev/null +++ b/crates/conjure_core/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "conjure_core" +version = "0.0.1" +edition = "2021" + +[dependencies] +serde = { version = "1.0.192", features = ["derive"] } +serde_json = "1.0.108" +serde_with = "3.4.0" +strum = "0.25.0" +strum_macros = "0.25.3" +thiserror = "1.0.50" + +[lints] +workspace = true diff --git a/crates/conjure_core/README.md b/crates/conjure_core/README.md new file mode 100644 index 000000000..5599950e6 --- /dev/null +++ b/crates/conjure_core/README.md @@ -0,0 +1,4 @@ +Core datatypes for use in Conjure Oxide. + +This crate is internal to conjure_oxide, and should not be treated as a stable +API. Relevant types are re-exported through conjure_oxide. diff --git a/conjure_oxide/src/ast.rs b/crates/conjure_core/src/ast.rs similarity index 100% rename from conjure_oxide/src/ast.rs rename to crates/conjure_core/src/ast.rs diff --git a/crates/conjure_core/src/lib.rs b/crates/conjure_core/src/lib.rs new file mode 100644 index 000000000..6471a8b4f --- /dev/null +++ b/crates/conjure_core/src/lib.rs @@ -0,0 +1,4 @@ +pub mod ast; + +pub mod solvers; +pub use solvers::Solver; diff --git a/conjure_oxide/src/solvers/solver_list.rs b/crates/conjure_core/src/solvers.rs similarity index 100% rename from conjure_oxide/src/solvers/solver_list.rs rename to crates/conjure_core/src/solvers.rs From 5d817557816da3fbcfd43e06aeffaedfbb947c7a Mon Sep 17 00:00:00 2001 From: Niklas Dewally Date: Wed, 6 Dec 2023 20:12:38 +0000 Subject: [PATCH 11/31] minion_rs: make the use of ffi functions clearer --- solvers/minion/src/error.rs | 4 +- .../minion/src/{raw_bindings.rs => ffi.rs} | 0 solvers/minion/src/lib.rs | 2 +- solvers/minion/src/run.rs | 85 ++++++++++--------- 4 files changed, 46 insertions(+), 45 deletions(-) rename solvers/minion/src/{raw_bindings.rs => ffi.rs} (100%) diff --git a/solvers/minion/src/error.rs b/solvers/minion/src/error.rs index d183da6c5..0cb498a0f 100644 --- a/solvers/minion/src/error.rs +++ b/solvers/minion/src/error.rs @@ -1,6 +1,6 @@ //! Error types for Minion bindings. -use crate::raw_bindings::*; +use crate::ffi; use thiserror::Error; /// A wrapper over all errors thrown by `minion_rs`. @@ -42,7 +42,7 @@ impl From for RuntimeError { fn from(return_code: u32) -> Self { match return_code { #[allow(non_upper_case_globals)] - ReturnCodes_INVALID_INSTANCE => RuntimeError::InvalidInstance, + ffi::ReturnCodes_INVALID_INSTANCE => RuntimeError::InvalidInstance, _ => RuntimeError::UnknownError, } } diff --git a/solvers/minion/src/raw_bindings.rs b/solvers/minion/src/ffi.rs similarity index 100% rename from solvers/minion/src/raw_bindings.rs rename to solvers/minion/src/ffi.rs diff --git a/solvers/minion/src/lib.rs b/solvers/minion/src/lib.rs index 48889019a..29f91550f 100644 --- a/solvers/minion/src/lib.rs +++ b/solvers/minion/src/lib.rs @@ -108,7 +108,7 @@ //! variable. Solutions are returned through the [callback function](Callback) as a `HashMap`. pub mod error; -mod raw_bindings; +mod ffi; mod run; pub use run::*; diff --git a/solvers/minion/src/run.rs b/solvers/minion/src/run.rs index 12da64e50..55c226d79 100644 --- a/solvers/minion/src/run.rs +++ b/solvers/minion/src/run.rs @@ -4,7 +4,8 @@ use std::{ sync::{Mutex, MutexGuard}, }; -use crate::{ast::*, error::*, raw_bindings::*, scoped_ptr::Scoped}; +use crate::ffi; +use crate::{ast::*, error::*, scoped_ptr::Scoped}; use anyhow::anyhow; // TODO: allow passing of options. @@ -131,7 +132,7 @@ unsafe extern "C" fn run_callback() -> bool { let mut solutions: HashMap = HashMap::new(); for (i, var) in print_vars.iter().enumerate() { - let solution_int: i32 = printMatrix_getValue(i as _); + let solution_int: i32 = ffi::printMatrix_getValue(i as _); let solution: Constant = Constant::Integer(solution_int); solutions.insert(var.to_string(), solution); } @@ -154,13 +155,13 @@ pub fn run_minion(model: Model, callback: Callback) -> Result<(), MinionError> { *CALLBACK.lock().unwrap() = Some(callback); unsafe { - let options = Scoped::new(newSearchOptions(), |x| searchOptions_free(x as _)); - let args = Scoped::new(newSearchMethod(), |x| searchMethod_free(x as _)); - let instance = Scoped::new(newInstance(), |x| instance_free(x as _)); + let options = Scoped::new(ffi::newSearchOptions(), |x| ffi::searchOptions_free(x as _)); + let args = Scoped::new(ffi::newSearchMethod(), |x| ffi::searchMethod_free(x as _)); + let instance = Scoped::new(ffi::newInstance(), |x| ffi::instance_free(x as _)); convert_model_to_raw(&instance, &model)?; - let res = runMinion(options.ptr, args.ptr, instance.ptr, Some(run_callback)); + let res = ffi::runMinion(options.ptr, args.ptr, instance.ptr, Some(run_callback)); match res { 0 => Ok(()), x => Err(MinionError::from(RuntimeError::from(x))), @@ -169,7 +170,7 @@ pub fn run_minion(model: Model, callback: Callback) -> Result<(), MinionError> { } unsafe fn convert_model_to_raw( - instance: &Scoped, + instance: &Scoped, model: &Model, ) -> Result<(), MinionError> { /*******************************/ @@ -185,7 +186,7 @@ unsafe fn convert_model_to_raw( * These are all done in the order saved in the SymbolTable. */ - let search_vars = Scoped::new(vec_var_new(), |x| vec_var_free(x as _)); + let search_vars = Scoped::new(ffi::vec_var_new(), |x| ffi::vec_var_free(x as _)); // store variables and the order they will be returned inside rust for later use. #[allow(clippy::unwrap_used)] @@ -206,11 +207,11 @@ unsafe fn convert_model_to_raw( .ok_or(anyhow!("Could not get var type for {:?}", var_name.clone()))?; let (vartype_raw, domain_low, domain_high) = match vartype { - VarDomain::Bound(a, b) => Ok((VariableType_VAR_BOUND, a, b)), + VarDomain::Bound(a, b) => Ok((ffi::VariableType_VAR_BOUND, a, b)), x => Err(MinionError::NotImplemented(format!("{:?}", x))), }?; - newVar_ffi( + ffi::newVar_ffi( instance.ptr, c_str.as_ptr() as _, vartype_raw, @@ -218,9 +219,9 @@ unsafe fn convert_model_to_raw( domain_high, ); - let var = getVarByName(instance.ptr, c_str.as_ptr() as _); + let var = ffi::getVarByName(instance.ptr, c_str.as_ptr() as _); - printMatrix_addVar(instance.ptr, var); + ffi::printMatrix_addVar(instance.ptr, var); // add to the print vars stored in rust so to remember // the order for callback function. @@ -228,15 +229,15 @@ unsafe fn convert_model_to_raw( #[allow(clippy::unwrap_used)] (*print_vars_guard).as_mut().unwrap().push(var_name.clone()); - vec_var_push_back(search_vars.ptr, var); + ffi::vec_var_push_back(search_vars.ptr, var); } let search_order = Scoped::new( - newSearchOrder(search_vars.ptr, VarOrderEnum_ORDER_STATIC, false), - |x| searchOrder_free(x as _), + ffi::newSearchOrder(search_vars.ptr, ffi::VarOrderEnum_ORDER_STATIC, false), + |x| ffi::searchOrder_free(x as _), ); - instance_addSearchOrder(instance.ptr, search_order.ptr); + ffi::instance_addSearchOrder(instance.ptr, search_order.ptr); /*********************************/ /* Add constraints */ @@ -248,12 +249,12 @@ unsafe fn convert_model_to_raw( // 3. add constraint to instance let constraint_type = get_constraint_type(constraint)?; - let raw_constraint = Scoped::new(newConstraintBlob(constraint_type), |x| { - constraint_free(x as _) + let raw_constraint = Scoped::new(ffi::newConstraintBlob(constraint_type), |x| { + ffi::constraint_free(x as _) }); constraint_add_args(instance.ptr, raw_constraint.ptr, constraint)?; - instance_addConstraint(instance.ptr, raw_constraint.ptr); + ffi::instance_addConstraint(instance.ptr, raw_constraint.ptr); } Ok(()) @@ -261,9 +262,9 @@ unsafe fn convert_model_to_raw( unsafe fn get_constraint_type(constraint: &Constraint) -> Result { match constraint { - Constraint::SumGeq(_, _) => Ok(ConstraintType_CT_GEQSUM), - Constraint::SumLeq(_, _) => Ok(ConstraintType_CT_LEQSUM), - Constraint::Ineq(_, _, _) => Ok(ConstraintType_CT_INEQ), + Constraint::SumGeq(_, _) => Ok(ffi::ConstraintType_CT_GEQSUM), + Constraint::SumLeq(_, _) => Ok(ffi::ConstraintType_CT_LEQSUM), + Constraint::Ineq(_, _, _) => Ok(ffi::ConstraintType_CT_INEQ), #[allow(unreachable_patterns)] x => Err(MinionError::NotImplemented(format!( "Constraint not implemented {:?}", @@ -273,8 +274,8 @@ unsafe fn get_constraint_type(constraint: &Constraint) -> Result Result<(), MinionError> { match constr { @@ -302,11 +303,11 @@ unsafe fn constraint_add_args( // DO NOT call manually - this assumes that all needed vars are already in the symbol table. // TODO not happy with this just assuming the name is in the symbol table unsafe fn read_vars( - instance: *mut ProbSpec_CSPInstance, - raw_constraint: *mut ProbSpec_ConstraintBlob, + instance: *mut ffi::ProbSpec_CSPInstance, + raw_constraint: *mut ffi::ProbSpec_ConstraintBlob, vars: &Vec, ) -> Result<(), MinionError> { - let raw_vars = Scoped::new(vec_var_new(), |x| vec_var_free(x as _)); + let raw_vars = Scoped::new(ffi::vec_var_new(), |x| ffi::vec_var_free(x as _)); for var in vars { let raw_var = match var { Var::NameRef(name) => { @@ -316,25 +317,25 @@ unsafe fn read_vars( name.clone() ) })?; - getVarByName(instance, c_str.as_ptr() as _) + ffi::getVarByName(instance, c_str.as_ptr() as _) } - Var::ConstantAsVar(n) => constantAsVar(*n), + Var::ConstantAsVar(n) => ffi::constantAsVar(*n), }; - vec_var_push_back(raw_vars.ptr, raw_var); + ffi::vec_var_push_back(raw_vars.ptr, raw_var); } - constraint_addVarList(raw_constraint, raw_vars.ptr); + ffi::constraint_addVarList(raw_constraint, raw_vars.ptr); Ok(()) } unsafe fn read_var( - instance: *mut ProbSpec_CSPInstance, - raw_constraint: *mut ProbSpec_ConstraintBlob, + instance: *mut ffi::ProbSpec_CSPInstance, + raw_constraint: *mut ffi::ProbSpec_ConstraintBlob, var: &Var, ) -> Result<(), MinionError> { - let raw_vars = Scoped::new(vec_var_new(), |x| vec_var_free(x as _)); + let raw_vars = Scoped::new(ffi::vec_var_new(), |x| ffi::vec_var_free(x as _)); let raw_var = match var { Var::NameRef(name) => { let c_str = CString::new(name.clone()).map_err(|_| { @@ -343,30 +344,30 @@ unsafe fn read_var( name.clone() ) })?; - getVarByName(instance, c_str.as_ptr() as _) + ffi::getVarByName(instance, c_str.as_ptr() as _) } - Var::ConstantAsVar(n) => constantAsVar(*n), + Var::ConstantAsVar(n) => ffi::constantAsVar(*n), }; - vec_var_push_back(raw_vars.ptr, raw_var); - constraint_addVarList(raw_constraint, raw_vars.ptr); + ffi::vec_var_push_back(raw_vars.ptr, raw_var); + ffi::constraint_addVarList(raw_constraint, raw_vars.ptr); Ok(()) } unsafe fn read_const( - raw_constraint: *mut ProbSpec_ConstraintBlob, + raw_constraint: *mut ffi::ProbSpec_ConstraintBlob, constant: &Constant, ) -> Result<(), MinionError> { - let raw_consts = Scoped::new(vec_int_new(), |x| vec_var_free(x as _)); + let raw_consts = Scoped::new(ffi::vec_int_new(), |x| ffi::vec_var_free(x as _)); let val = match constant { Constant::Integer(n) => Ok(n), x => Err(MinionError::NotImplemented(format!("{:?}", x))), }?; - vec_int_push_back(raw_consts.ptr, *val); - constraint_addConstantList(raw_constraint, raw_consts.ptr); + ffi::vec_int_push_back(raw_consts.ptr, *val); + ffi::constraint_addConstantList(raw_constraint, raw_consts.ptr); Ok(()) } From 8fed76307a88fd3276866cec330b350119d4484a Mon Sep 17 00:00:00 2001 From: Felix Date: Tue, 23 Jan 2024 16:03:32 +0000 Subject: [PATCH 12/31] add missing import --- solvers/minion/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/solvers/minion/src/lib.rs b/solvers/minion/src/lib.rs index 835cda3c6..ffb2661aa 100644 --- a/solvers/minion/src/lib.rs +++ b/solvers/minion/src/lib.rs @@ -29,6 +29,7 @@ //! use minion_rs::ast::*; //! use minion_rs::run_minion; //! use std::collections::HashMap; +//! use std::sync::Mutex; //! //! // Get solutions out of Minion. //! // See the documentation for Callback for details. From d61501829d8340c80b565d4ebd7f0d0cae2e6561 Mon Sep 17 00:00:00 2001 From: Felix Date: Mon, 22 Jan 2024 14:53:33 +0000 Subject: [PATCH 13/31] Define rule struct and give example definition Co-authored-by: Nik --- conjure_oxide/src/lib.rs | 1 + conjure_oxide/src/rules/mod.rs | 11 ++++++++++ crates/conjure_core/src/lib.rs | 1 + crates/conjure_core/src/rule.rs | 36 +++++++++++++++++++++++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 conjure_oxide/src/rules/mod.rs create mode 100644 crates/conjure_core/src/rule.rs diff --git a/conjure_oxide/src/lib.rs b/conjure_oxide/src/lib.rs index c2c17a283..e7f1a854a 100644 --- a/conjure_oxide/src/lib.rs +++ b/conjure_oxide/src/lib.rs @@ -1,6 +1,7 @@ pub mod error; pub mod find_conjure; pub mod parse; +pub mod rules; mod solvers; pub use conjure_core::ast; // re-export core::ast as conjure_oxide::ast diff --git a/conjure_oxide/src/rules/mod.rs b/conjure_oxide/src/rules/mod.rs new file mode 100644 index 000000000..3911c82ed --- /dev/null +++ b/conjure_oxide/src/rules/mod.rs @@ -0,0 +1,11 @@ +use conjure_core::ast::Expression; +use conjure_core::rule::{Rule, RuleApplicationError}; + +fn identity(expr: &Expression) -> Result { + Ok(expr.clone()) +} + +pub static IDENTITY_RULE: Rule = Rule { + name: "identity", + application: identity, +}; diff --git a/crates/conjure_core/src/lib.rs b/crates/conjure_core/src/lib.rs index 6471a8b4f..df41804d3 100644 --- a/crates/conjure_core/src/lib.rs +++ b/crates/conjure_core/src/lib.rs @@ -1,4 +1,5 @@ pub mod ast; +pub mod rule; pub mod solvers; pub use solvers::Solver; diff --git a/crates/conjure_core/src/rule.rs b/crates/conjure_core/src/rule.rs new file mode 100644 index 000000000..059e738a9 --- /dev/null +++ b/crates/conjure_core/src/rule.rs @@ -0,0 +1,36 @@ +use std::fmt::{self, Display, Formatter}; + +use thiserror::Error; + +use crate::ast::Expression; + +#[derive(Debug, Error)] +pub enum RuleApplicationError { + #[error("Rule is not applicable")] + RuleNotApplicable, +} + +#[derive(Clone, Debug)] +pub struct Rule<'a> { + pub name: &'a str, + pub application: fn(&Expression) -> Result, +} + +impl<'a> Rule<'a> { + pub fn new( + name: &'a str, + application: fn(&Expression) -> Result, + ) -> Self { + Self { name, application } + } + + pub fn apply(&self, expr: &Expression) -> Result { + (self.application)(expr) + } +} + +impl<'a> Display for Rule<'a> { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.name) + } +} From b4a0a77a59f93f47c97120bf77e97da45ea8cf97 Mon Sep 17 00:00:00 2001 From: Felix Date: Tue, 23 Jan 2024 15:08:11 +0000 Subject: [PATCH 14/31] add rule registry and sanity check --- Cargo.lock | 39 +++++++++++++++++++++++++++ Cargo.toml | 2 ++ conjure_oxide/Cargo.toml | 2 ++ conjure_oxide/src/lib.rs | 1 - conjure_oxide/src/main.rs | 6 ++--- conjure_oxide/src/rules/mod.rs | 11 -------- conjure_oxide/tests/rewrite_tests.rs | 6 +++++ crates/conjure_macros/Cargo.toml | 14 ++++++++++ crates/conjure_macros/src/lib.rs | 28 +++++++++++++++++++ crates/conjure_rules/Cargo.toml | 12 +++++++++ crates/conjure_rules/src/lib.rs | 13 +++++++++ crates/conjure_rules/src/rules/mod.rs | 8 ++++++ 12 files changed, 126 insertions(+), 16 deletions(-) delete mode 100644 conjure_oxide/src/rules/mod.rs create mode 100644 crates/conjure_macros/Cargo.toml create mode 100644 crates/conjure_macros/src/lib.rs create mode 100644 crates/conjure_rules/Cargo.toml create mode 100644 crates/conjure_rules/src/lib.rs create mode 100644 crates/conjure_rules/src/rules/mod.rs diff --git a/Cargo.lock b/Cargo.lock index b13643407..f76eb577e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -270,6 +270,14 @@ dependencies = [ "thiserror", ] +[[package]] +name = "conjure_macros" +version = "0.1.0" +dependencies = [ + "quote", + "syn 2.0.48", +] + [[package]] name = "conjure_oxide" version = "0.0.1" @@ -277,6 +285,8 @@ dependencies = [ "anyhow", "clap", "conjure_core", + "conjure_rules", + "linkme", "minion_rs", "serde", "serde_json", @@ -288,6 +298,15 @@ dependencies = [ "walkdir", ] +[[package]] +name = "conjure_rules" +version = "0.1.0" +dependencies = [ + "conjure_core", + "conjure_macros", + "linkme", +] + [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -555,6 +574,26 @@ dependencies = [ "winapi", ] +[[package]] +name = "linkme" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b53ad6a33de58864705954edb5ad5d571a010f9e296865ed43dc72a5621b430" +dependencies = [ + "linkme-impl", +] + +[[package]] +name = "linkme-impl" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04e542a18c94a9b6fcc7adb090fa3ba6b79ee220a16404f325672729f32a66ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "linux-raw-sys" version = "0.4.11" diff --git a/Cargo.toml b/Cargo.toml index 834320ce1..e59889883 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,8 @@ resolver = "2" members = [ "conjure_oxide", "crates/conjure_core", + "crates/conjure_macros", + "crates/conjure_rules", "solvers/kissat", "solvers/minion", "solvers/chuffed", diff --git a/conjure_oxide/Cargo.toml b/conjure_oxide/Cargo.toml index 7015b3012..70e6a2107 100644 --- a/conjure_oxide/Cargo.toml +++ b/conjure_oxide/Cargo.toml @@ -10,6 +10,7 @@ walkdir = "2.4.0" [dependencies] conjure_core = {path = "../crates/conjure_core" } +conjure_rules = {path = "../crates/conjure_rules" } serde = { version = "1.0.195", features = ["derive"] } serde_json = "1.0.111" @@ -21,6 +22,7 @@ clap = { version = "4.4.16", features = ["derive"] } strum_macros = "0.25.3" strum = "0.25.0" versions = "6.1.0" +linkme = "0.3.22" [lints] workspace = true diff --git a/conjure_oxide/src/lib.rs b/conjure_oxide/src/lib.rs index e7f1a854a..c2c17a283 100644 --- a/conjure_oxide/src/lib.rs +++ b/conjure_oxide/src/lib.rs @@ -1,7 +1,6 @@ pub mod error; pub mod find_conjure; pub mod parse; -pub mod rules; mod solvers; pub use conjure_core::ast; // re-export core::ast as conjure_oxide::ast diff --git a/conjure_oxide/src/main.rs b/conjure_oxide/src/main.rs index 6452d82a9..0699ff379 100644 --- a/conjure_oxide/src/main.rs +++ b/conjure_oxide/src/main.rs @@ -19,6 +19,8 @@ struct Cli { } pub fn main() -> AnyhowResult<()> { + println!("Rules: {:?}", conjure_rules::get_rules()); + let cli = Cli::parse(); println!("Input file: {}", cli.input_file.display()); let input_file: &str = cli.input_file.to_str().ok_or(anyhow!( @@ -48,9 +50,5 @@ pub fn main() -> AnyhowResult<()> { let model = model_from_json(&astjson)?; println!("{:?}", model); - // for rule in get_rules_by_kind() { - // println!("Applying rule {:?}", rule); - // } - Ok(()) } diff --git a/conjure_oxide/src/rules/mod.rs b/conjure_oxide/src/rules/mod.rs deleted file mode 100644 index 3911c82ed..000000000 --- a/conjure_oxide/src/rules/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -use conjure_core::ast::Expression; -use conjure_core::rule::{Rule, RuleApplicationError}; - -fn identity(expr: &Expression) -> Result { - Ok(expr.clone()) -} - -pub static IDENTITY_RULE: Rule = Rule { - name: "identity", - application: identity, -}; diff --git a/conjure_oxide/tests/rewrite_tests.rs b/conjure_oxide/tests/rewrite_tests.rs index 13e4a6779..0061c6efe 100644 --- a/conjure_oxide/tests/rewrite_tests.rs +++ b/conjure_oxide/tests/rewrite_tests.rs @@ -4,6 +4,12 @@ use core::panic; use conjure_oxide::ast::*; +#[test] +fn rules_present() { + let rules = conjure_rules::get_rules(); + assert!(rules.len() > 0); +} + #[test] fn sum_of_constants() { let valid_sum_expression = Expression::Sum(vec![ diff --git a/crates/conjure_macros/Cargo.toml b/crates/conjure_macros/Cargo.toml new file mode 100644 index 000000000..f5d6fa13a --- /dev/null +++ b/crates/conjure_macros/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "conjure_macros" +version = "0.1.0" +edition = "2021" + +[lib] +proc_macro = true + +[dependencies] +quote = "1.0.34" +syn = { version = "2.0.43", features = ["full"] } + +[lints] +workspace = true diff --git a/crates/conjure_macros/src/lib.rs b/crates/conjure_macros/src/lib.rs new file mode 100644 index 000000000..49567371c --- /dev/null +++ b/crates/conjure_macros/src/lib.rs @@ -0,0 +1,28 @@ +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, Ident, ItemFn}; + +#[proc_macro_attribute] +/// This procedural macro registers a decorated function with Conjure's rule engine. +/// Functions must have the signature `fn(&Expr) -> Result`. +/// +/// Intermediary static variables are created to allow for the decentralized registry, with the prefix `CONJURE_GEN_`. +/// Please ensure that other variable names in the same scope do not conflict with these. +pub fn register_rule(_: TokenStream, item: TokenStream) -> TokenStream { + let func = parse_macro_input!(item as ItemFn); + let rule_ident = &func.sig.ident; + let static_name = format!("CONJURE_GEN_RULE_{}", rule_ident).to_uppercase(); + let static_ident = Ident::new(&static_name, rule_ident.span()); + + let expanded = quote! { + #func + + #[::linkme::distributed_slice(_RULES_DISTRIBUTED_SLICE)] + pub static #static_ident: ::conjure_core::rule::Rule = ::conjure_core::rule::Rule { + name: stringify!(#rule_ident), + application: #rule_ident, + }; + }; + + TokenStream::from(expanded) +} diff --git a/crates/conjure_rules/Cargo.toml b/crates/conjure_rules/Cargo.toml new file mode 100644 index 000000000..0a4f06d7c --- /dev/null +++ b/crates/conjure_rules/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "conjure_rules" +version = "0.1.0" +edition = "2021" + +[dependencies] +conjure_macros = { path = "../conjure_macros" } +conjure_core = { path = "../conjure_core" } +linkme = "0.3.22" + +[lints] +workspace = true diff --git a/crates/conjure_rules/src/lib.rs b/crates/conjure_rules/src/lib.rs new file mode 100644 index 000000000..49c9f8c7c --- /dev/null +++ b/crates/conjure_rules/src/lib.rs @@ -0,0 +1,13 @@ +use conjure_core::rule::Rule; +use linkme::distributed_slice; + +#[distributed_slice] +pub static _RULES_DISTRIBUTED_SLICE: [Rule<'static>]; + +pub fn get_rules() -> Vec> { + _RULES_DISTRIBUTED_SLICE.to_vec() +} + +mod rules; + +static _TEMP: &Rule = &rules::CONJURE_GEN_RULE_IDENTITY; // Temporary hack to force the static to be included in the binary diff --git a/crates/conjure_rules/src/rules/mod.rs b/crates/conjure_rules/src/rules/mod.rs new file mode 100644 index 000000000..27682650d --- /dev/null +++ b/crates/conjure_rules/src/rules/mod.rs @@ -0,0 +1,8 @@ +use crate::_RULES_DISTRIBUTED_SLICE; +use conjure_core::{ast::Expression, rule::RuleApplicationError}; +use conjure_macros::register_rule; + +#[register_rule] +fn identity(expr: &Expression) -> Result { + Ok(expr.clone()) +} From b9f77ea4a60ea087378da27b310ff46e1ab54ae1 Mon Sep 17 00:00:00 2001 From: Niklas Dewally Date: Tue, 23 Jan 2024 18:44:23 +0000 Subject: [PATCH 15/31] fix: replace the linkme hack with a slightly less bad one --- Cargo.toml | 6 ++++++ crates/conjure_rules/src/lib.rs | 2 -- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e59889883..39f4190a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,3 +13,9 @@ members = [ [workspace.lints.clippy] unwrap_used = "warn" expect_used = "warn" + +[profile.dev] +codegen-units = 1 + +[profile.release] +codegen-units = 1 diff --git a/crates/conjure_rules/src/lib.rs b/crates/conjure_rules/src/lib.rs index 49c9f8c7c..ff4cd7590 100644 --- a/crates/conjure_rules/src/lib.rs +++ b/crates/conjure_rules/src/lib.rs @@ -9,5 +9,3 @@ pub fn get_rules() -> Vec> { } mod rules; - -static _TEMP: &Rule = &rules::CONJURE_GEN_RULE_IDENTITY; // Temporary hack to force the static to be included in the binary From 0ffd437ce8dfc75c91f5ecd511528e6fcad34502 Mon Sep 17 00:00:00 2001 From: Felix Date: Tue, 23 Jan 2024 16:03:32 +0000 Subject: [PATCH 16/31] add missing import --- solvers/minion/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/solvers/minion/src/lib.rs b/solvers/minion/src/lib.rs index 835cda3c6..ffb2661aa 100644 --- a/solvers/minion/src/lib.rs +++ b/solvers/minion/src/lib.rs @@ -29,6 +29,7 @@ //! use minion_rs::ast::*; //! use minion_rs::run_minion; //! use std::collections::HashMap; +//! use std::sync::Mutex; //! //! // Get solutions out of Minion. //! // See the documentation for Callback for details. From 6de80f06374eda616e6fcadb95eb80efc66354ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 21:48:59 +0000 Subject: [PATCH 17/31] Bump shlex from 1.2.0 to 1.3.0 Bumps [shlex](https://github.com/comex/rust-shlex) from 1.2.0 to 1.3.0. - [Changelog](https://github.com/comex/rust-shlex/blob/master/CHANGELOG.md) - [Commits](https://github.com/comex/rust-shlex/commits) --- updated-dependencies: - dependency-name: shlex dependency-type: indirect ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b13643407..8aac4f059 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -785,9 +785,9 @@ dependencies = [ [[package]] name = "shlex" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "strsim" From 77fe6d101c1d5c7cc4b5cebcb2ff0d1fb7169a59 Mon Sep 17 00:00:00 2001 From: Niklas Dewally Date: Tue, 23 Jan 2024 19:15:08 +0000 Subject: [PATCH 18/31] ci: run all combinations of tests in matrix, even if one combination fails --- .github/workflows/test.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 396cc68cc..f2720877e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,12 +15,11 @@ on: - .github/workflows/test.yml workflow_dispatch: - jobs: - Job: - strategy: + # run all combinations of the matrix even if one combination fails. + fail-fast: false matrix: rust_release: - stable From 70d0f9f7c14ab5922d49ec4e97a034cfab739184 Mon Sep 17 00:00:00 2001 From: Niklas Dewally Date: Tue, 23 Jan 2024 19:17:26 +0000 Subject: [PATCH 19/31] ci: trigger tests on changes to all crates, not just changes to conjure oxide --- .github/workflows/test.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f2720877e..6ebcf1806 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,11 +6,15 @@ on: - main # run for pushes to the main branch. other branches need to create a PR if they want testing. paths: - conjure_oxide/** + - solvers/** + - crates/** - Cargo.* - .github/workflows/test.yml pull_request: paths: - conjure_oxide/** + - solvers/** + - crates/** - Cargo.* - .github/workflows/test.yml workflow_dispatch: From 8844a2a418dc8a5b6fae0ffe750b0fb4b9e81b77 Mon Sep 17 00:00:00 2001 From: Niklas Dewally Date: Tue, 23 Jan 2024 19:18:41 +0000 Subject: [PATCH 20/31] ci: run build and test on all members of the workspace, not just the default ones --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6ebcf1806..8fee7b1c7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -60,7 +60,7 @@ jobs: - run: rustup update ${{ matrix.rust_release }} && rustup default ${{ matrix.rust_release }} - - run: cargo build -vv + - run: cargo build -vv --workspace - name: Add conjure to PATH run: echo "${HOME}/.cargo/bin/conjure-v${{ matrix.conjure_version }}-${{ matrix.release_suffix }}-with-solvers" >> ${GITHUB_PATH} @@ -79,6 +79,6 @@ jobs: fi conjure --version - - run: cargo test + - run: cargo test --workspace - - run: cargo audit + - run: cargo audit --workspace From 1d088ea9c6e7b527019402c6b639432d3bf38bf4 Mon Sep 17 00:00:00 2001 From: Niklas Dewally Date: Tue, 23 Jan 2024 19:24:25 +0000 Subject: [PATCH 21/31] ci: seperate dependency audit job from build and test check --- .github/workflows/test.yml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8fee7b1c7..52f137595 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,7 +20,8 @@ on: workflow_dispatch: jobs: - Job: + build-and-test: + name: "Build and Test" strategy: # run all combinations of the matrix even if one combination fails. fail-fast: false @@ -81,4 +82,17 @@ jobs: - run: cargo test --workspace - - run: cargo audit --workspace + audit: + name: "Dependency Audit" + runs-on: ubuntu-latest + strategy: + # run all combinations of the matrix even if one combination fails. + fail-fast: false + matrix: + rust_release: + - stable + - nightly + steps: + - uses: actions/checkout@v3 + - run: rustup update ${{ matrix.rust_release }} && rustup default ${{ matrix.rust_release }} + - run: cargo audit From 5c61888a1a60955d43d2b3deea21bb6d883944d1 Mon Sep 17 00:00:00 2001 From: Niklas Dewally Date: Tue, 23 Jan 2024 19:26:56 +0000 Subject: [PATCH 22/31] ci: rename docs.yml to docs-generate.yml for clarity --- .github/workflows/docs-deploy.yml | 2 +- .github/workflows/{docs.yml => docs-generate.yml} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename .github/workflows/{docs.yml => docs-generate.yml} (100%) diff --git a/.github/workflows/docs-deploy.yml b/.github/workflows/docs-deploy.yml index c77673292..f99d71472 100644 --- a/.github/workflows/docs-deploy.yml +++ b/.github/workflows/docs-deploy.yml @@ -42,7 +42,7 @@ jobs: uses: dawidd6/action-download-artifact@v2 with: name: docs-${{ steps.sha.outputs.result }} - workflow: docs.yml + workflow: docs-generate.yml path: ./deploy - name: Deploy to Github Pages diff --git a/.github/workflows/docs.yml b/.github/workflows/docs-generate.yml similarity index 100% rename from .github/workflows/docs.yml rename to .github/workflows/docs-generate.yml From 7282e0e28207aad700c497e27249b9578c55788c Mon Sep 17 00:00:00 2001 From: Niklas Dewally Date: Tue, 23 Jan 2024 19:27:21 +0000 Subject: [PATCH 23/31] ci: run format and coverage on changes to crates in crates/ --- .github/workflows/code-coverage.yml | 2 ++ .github/workflows/doc-coverage.yml | 2 ++ .github/workflows/format.yml | 2 ++ 3 files changed, 6 insertions(+) diff --git a/.github/workflows/code-coverage.yml b/.github/workflows/code-coverage.yml index 49f259d3b..a62476b7b 100644 --- a/.github/workflows/code-coverage.yml +++ b/.github/workflows/code-coverage.yml @@ -8,12 +8,14 @@ on: - Cargo.* - conjure-oxide/** - solvers/** + - crates/** - .github/actions/code-coverage.yml pull_request: paths: - Cargo.* - conjure-oxide/** - solvers/** + - crates/** - .github/actions/code-coverage.yml workflow_dispatch: diff --git a/.github/workflows/doc-coverage.yml b/.github/workflows/doc-coverage.yml index b3525e0da..aa5cfb79e 100644 --- a/.github/workflows/doc-coverage.yml +++ b/.github/workflows/doc-coverage.yml @@ -8,12 +8,14 @@ on: - Cargo.* - conjure-oxide/** - solvers/** + - crates/** - .github/actions/doc-coverage.yml pull_request: paths: - Cargo.* - conjure-oxide/** - solvers/** + - crates/** - .github/actions/doc-coverage.yml workflow_dispatch: diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index e86856d72..ac52dce62 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -10,12 +10,14 @@ on: - Cargo.* - conjure-oxide/** - solvers/** + - crates/** - .github/actions/format.yml pull_request: paths: - Cargo.* - conjure-oxide/** - solvers/** + - crates/** - .github/actions/format.yml workflow_dispatch: From 22234d103c7fe221a0a4d72534bc4bc3ee0fbde7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 08:49:23 +0000 Subject: [PATCH 24/31] Bump the all group with 2 updates Bumps the all group with 2 updates: [serde_with](https://github.com/jonasbb/serde_with) and [clap](https://github.com/clap-rs/clap). Updates `serde_with` from 3.4.0 to 3.5.0 - [Release notes](https://github.com/jonasbb/serde_with/releases) - [Commits](https://github.com/jonasbb/serde_with/compare/v3.4.0...v3.5.0) Updates `clap` from 4.4.16 to 4.4.18 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v4.4.16...v4.4.18) --- updated-dependencies: - dependency-name: serde_with dependency-type: direct:production update-type: version-update:semver-minor dependency-group: all - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all ... Signed-off-by: dependabot[bot] --- Cargo.lock | 16 ++++++++-------- conjure_oxide/Cargo.toml | 4 ++-- crates/conjure_core/Cargo.toml | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8aac4f059..ae9c35efc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -214,9 +214,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.16" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58e54881c004cec7895b0068a0a954cd5d62da01aef83fa35b1e594497bf5445" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" dependencies = [ "clap_builder", "clap_derive", @@ -224,9 +224,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.16" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59cb82d7f531603d2fd1f507441cdd35184fa81beff7bd489570de7f773460bb" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" dependencies = [ "anstream", "anstyle", @@ -756,9 +756,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" +checksum = "f58c3a1b3e418f61c25b2aeb43fc6c95eaa252b8cecdda67f401943e9e08d33f" dependencies = [ "base64", "chrono", @@ -773,9 +773,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" +checksum = "d2068b437a31fc68f25dd7edc296b078f04b45145c199d8eed9866e45f1ff274" dependencies = [ "darling", "proc-macro2", diff --git a/conjure_oxide/Cargo.toml b/conjure_oxide/Cargo.toml index 7015b3012..a93d46eef 100644 --- a/conjure_oxide/Cargo.toml +++ b/conjure_oxide/Cargo.toml @@ -13,11 +13,11 @@ conjure_core = {path = "../crates/conjure_core" } serde = { version = "1.0.195", features = ["derive"] } serde_json = "1.0.111" -serde_with = "3.4.0" +serde_with = "3.5.0" thiserror = "1.0.56" minion_rs = {path = "../solvers/minion" } anyhow = "1.0.79" -clap = { version = "4.4.16", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } strum_macros = "0.25.3" strum = "0.25.0" versions = "6.1.0" diff --git a/crates/conjure_core/Cargo.toml b/crates/conjure_core/Cargo.toml index bc4f96610..66a405fda 100644 --- a/crates/conjure_core/Cargo.toml +++ b/crates/conjure_core/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] serde = { version = "1.0.192", features = ["derive"] } serde_json = "1.0.108" -serde_with = "3.4.0" +serde_with = "3.5.0" strum = "0.25.0" strum_macros = "0.25.3" thiserror = "1.0.50" From d30c2be3475945c3350c83dbf629ebe53da9581a Mon Sep 17 00:00:00 2001 From: Niklas Dewally Date: Tue, 23 Jan 2024 23:06:33 +0000 Subject: [PATCH 25/31] make rule macro safe to use everywhere, and move rules into conjure_oxide. This commit makes the rule macro safe to use in all crates, not just conjure_rules. This allows for completely decentralised definition of rules, without the user having to worrying about dependencies. Previously, the macro expansion made imports from external crates, which would break when used in crates that did not explicitly list said crates in their Cargo.toml. Some simple solutions to this are to limit use of the macro to a single crate, or to force users to add stuff to their Cargo.toml. These are both non-ideal: the former limits how "decentralised" rule definition could be; the latter is a leaky abstraction and would make updating this crate difficult for a user. See: - https://users.rust-lang.org/t/proc-macros-using-third-party-crate/42465/4 - https://doc.rust-lang.org/reference/procedural-macros.html#procedural-macro-hygiene Procedural macros and external crate imports ============================================== Procedural macros are unhygienic - they directly substitute into source code, and do not have their own scope, imports, and so on. Therefore, we cannot assume the user has any dependencies apart from the one they imported the macro from. (Also, note Rust does not bring transitive dependencies into scope, so we cannot assume the presence of a dependency of the crate.) To solve this, the crate the macro is in must re-export everything the macro needs to run. However, proc-macro crates can only export proc-macros. Therefore, we must use a "front end crate" to re-export both the macro and all the things it may need. Conjure_rules is the frontend crate, and re-exports the macro from conjure_rules_proc_macro. --- Cargo.lock | 19 +++++----- Cargo.toml | 2 +- conjure_oxide/src/lib.rs | 1 + .../src/rules/mod.rs | 3 +- crates/conjure_rules/Cargo.toml | 2 +- crates/conjure_rules/src/lib.rs | 35 +++++++++++++++++-- .../Cargo.toml | 3 +- .../src/lib.rs | 5 +-- 8 files changed, 51 insertions(+), 19 deletions(-) rename {crates/conjure_rules => conjure_oxide}/src/rules/mod.rs (71%) rename crates/{conjure_macros => conjure_rules_proc_macro}/Cargo.toml (70%) rename crates/{conjure_macros => conjure_rules_proc_macro}/src/lib.rs (81%) diff --git a/Cargo.lock b/Cargo.lock index 54cc87905..2bd606f88 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -270,14 +270,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "conjure_macros" -version = "0.1.0" -dependencies = [ - "quote", - "syn 2.0.48", -] - [[package]] name = "conjure_oxide" version = "0.0.1" @@ -303,10 +295,19 @@ name = "conjure_rules" version = "0.1.0" dependencies = [ "conjure_core", - "conjure_macros", + "conjure_rules_proc_macro", "linkme", ] +[[package]] +name = "conjure_rules_proc_macro" +version = "0.1.0" +dependencies = [ + "conjure_core", + "quote", + "syn 2.0.48", +] + [[package]] name = "core-foundation-sys" version = "0.8.4" diff --git a/Cargo.toml b/Cargo.toml index 39f4190a3..67bae205d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "2" members = [ "conjure_oxide", "crates/conjure_core", - "crates/conjure_macros", + "crates/conjure_rules_proc_macro", "crates/conjure_rules", "solvers/kissat", "solvers/minion", diff --git a/conjure_oxide/src/lib.rs b/conjure_oxide/src/lib.rs index c2c17a283..022ac9106 100644 --- a/conjure_oxide/src/lib.rs +++ b/conjure_oxide/src/lib.rs @@ -1,6 +1,7 @@ pub mod error; pub mod find_conjure; pub mod parse; +mod rules; mod solvers; pub use conjure_core::ast; // re-export core::ast as conjure_oxide::ast diff --git a/crates/conjure_rules/src/rules/mod.rs b/conjure_oxide/src/rules/mod.rs similarity index 71% rename from crates/conjure_rules/src/rules/mod.rs rename to conjure_oxide/src/rules/mod.rs index 27682650d..4d4702c64 100644 --- a/crates/conjure_rules/src/rules/mod.rs +++ b/conjure_oxide/src/rules/mod.rs @@ -1,6 +1,5 @@ -use crate::_RULES_DISTRIBUTED_SLICE; use conjure_core::{ast::Expression, rule::RuleApplicationError}; -use conjure_macros::register_rule; +use conjure_rules::register_rule; #[register_rule] fn identity(expr: &Expression) -> Result { diff --git a/crates/conjure_rules/Cargo.toml b/crates/conjure_rules/Cargo.toml index 0a4f06d7c..563888c59 100644 --- a/crates/conjure_rules/Cargo.toml +++ b/crates/conjure_rules/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -conjure_macros = { path = "../conjure_macros" } +conjure_rules_proc_macro = { path = "../conjure_rules_proc_macro" } conjure_core = { path = "../conjure_core" } linkme = "0.3.22" diff --git a/crates/conjure_rules/src/lib.rs b/crates/conjure_rules/src/lib.rs index ff4cd7590..26c8a85f4 100644 --- a/crates/conjure_rules/src/lib.rs +++ b/crates/conjure_rules/src/lib.rs @@ -1,11 +1,40 @@ +//! Rule registry for conjure_oxide. +//! TODO: doc comment. +//! + +// Why all the re-exports and wierdness? +// ============================ +// +// Procedural macros are unhygenic - they directly subsitute into source code, and do not have +// their own scope, imports, and so on. +// +// See [https://doc.rust-lang.org/reference/procedural-macros.html#procedural-macro-hygiene]. +// +// Therefore, we cannot assume the user has any dependencies apart from the one they imported the +// macro from. (Also, note Rust does not bring transitive dependencies into scope, so we cannot +// assume the presence of a dependency of the crate.) +// +// To solve this, the crate the macro is in must re-export everything the macro needs to run. +// +// However, proc-macro crates can only export proc-macros. Therefore, we must use a "front end +// crate" (i.e. this one) to re-export both the macro and all the things it may need. + use conjure_core::rule::Rule; use linkme::distributed_slice; +#[doc(hidden)] +pub mod _dependencies { + pub use conjure_core::rule::Rule; + pub use linkme::distributed_slice; +} + +#[doc(hidden)] #[distributed_slice] -pub static _RULES_DISTRIBUTED_SLICE: [Rule<'static>]; +pub static RULES_DISTRIBUTED_SLICE: [Rule<'static>]; pub fn get_rules() -> Vec> { - _RULES_DISTRIBUTED_SLICE.to_vec() + RULES_DISTRIBUTED_SLICE.to_vec() } -mod rules; +/// TODO: docs +pub use conjure_rules_proc_macro::register_rule; diff --git a/crates/conjure_macros/Cargo.toml b/crates/conjure_rules_proc_macro/Cargo.toml similarity index 70% rename from crates/conjure_macros/Cargo.toml rename to crates/conjure_rules_proc_macro/Cargo.toml index f5d6fa13a..a5661e5b8 100644 --- a/crates/conjure_macros/Cargo.toml +++ b/crates/conjure_rules_proc_macro/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "conjure_macros" +name = "conjure_rules_proc_macro" version = "0.1.0" edition = "2021" @@ -8,6 +8,7 @@ proc_macro = true [dependencies] quote = "1.0.34" +conjure_core = {path= "../conjure_core"} syn = { version = "2.0.43", features = ["full"] } [lints] diff --git a/crates/conjure_macros/src/lib.rs b/crates/conjure_rules_proc_macro/src/lib.rs similarity index 81% rename from crates/conjure_macros/src/lib.rs rename to crates/conjure_rules_proc_macro/src/lib.rs index 49567371c..bf89079eb 100644 --- a/crates/conjure_macros/src/lib.rs +++ b/crates/conjure_rules_proc_macro/src/lib.rs @@ -2,6 +2,7 @@ use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, Ident, ItemFn}; +#[doc(hidden)] #[proc_macro_attribute] /// This procedural macro registers a decorated function with Conjure's rule engine. /// Functions must have the signature `fn(&Expr) -> Result`. @@ -17,8 +18,8 @@ pub fn register_rule(_: TokenStream, item: TokenStream) -> TokenStream { let expanded = quote! { #func - #[::linkme::distributed_slice(_RULES_DISTRIBUTED_SLICE)] - pub static #static_ident: ::conjure_core::rule::Rule = ::conjure_core::rule::Rule { + #[::conjure_rules::_dependencies::distributed_slice(::conjure_rules::RULES_DISTRIBUTED_SLICE)] + pub static #static_ident: ::conjure_rules::_dependencies::Rule = ::conjure_rules::_dependencies::Rule { name: stringify!(#rule_ident), application: #rule_ident, }; From c1d7a9ff196f46e2976867204dfa98bb6142d1c6 Mon Sep 17 00:00:00 2001 From: Felix Date: Wed, 24 Jan 2024 23:26:47 +0000 Subject: [PATCH 26/31] add documentation to rule registry features --- crates/conjure_rules/src/lib.rs | 32 ++++++++++++++++-- crates/conjure_rules_proc_macro/src/lib.rs | 38 +++++++++++++++++++++- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/crates/conjure_rules/src/lib.rs b/crates/conjure_rules/src/lib.rs index 26c8a85f4..d7e45fb95 100644 --- a/crates/conjure_rules/src/lib.rs +++ b/crates/conjure_rules/src/lib.rs @@ -1,5 +1,8 @@ -//! Rule registry for conjure_oxide. -//! TODO: doc comment. +//! ### A decentralised rule registry for Conjure Oxide +//! +//! This crate allows registering valid functions as expression-reduction rules. +//! Functions can be decorated with the `register_rule` macro in any downstream crate and be used by Conjure Oxide's rule engine. +//! To achieve compile-time linking, we make use of the [`linkme`](https://docs.rs/linkme/latest/linkme/) crate. //! // Why all the re-exports and wierdness? @@ -32,9 +35,32 @@ pub mod _dependencies { #[distributed_slice] pub static RULES_DISTRIBUTED_SLICE: [Rule<'static>]; +/// Returns a copied `Vec` of all rules registered with the `register_rule` macro. +/// +/// Rules defined in the same file will remain contiguous and in order, but order may not be maintained between files. +/// +/// # Example +/// ```rust +/// use conjure_rules::register_rule; +/// use conjure_oxide::rule::{Rule, RuleApplicationError}; +/// +/// #[register_rule] +/// fn identity(expr: &Expression) -> Result { +/// Ok(expr.clone()) +/// } +/// +/// fn main() { +/// println!("Rules: {:?}", conjure_rules::get_rules()); +/// } +/// ``` +/// +/// This will print (if no other rules are registered): +/// ```text +/// Rules: [Rule { name: "identity", application: MEM }] +/// ``` +/// Where `MEM` is the memory address of the `identity` function. pub fn get_rules() -> Vec> { RULES_DISTRIBUTED_SLICE.to_vec() } -/// TODO: docs pub use conjure_rules_proc_macro::register_rule; diff --git a/crates/conjure_rules_proc_macro/src/lib.rs b/crates/conjure_rules_proc_macro/src/lib.rs index bf89079eb..5bc4880aa 100644 --- a/crates/conjure_rules_proc_macro/src/lib.rs +++ b/crates/conjure_rules_proc_macro/src/lib.rs @@ -4,11 +4,47 @@ use syn::{parse_macro_input, Ident, ItemFn}; #[doc(hidden)] #[proc_macro_attribute] -/// This procedural macro registers a decorated function with Conjure's rule engine. +/// This procedural macro registers a decorated function with `conjure_rules`' global registry. +/// It may be used in any downstream crate. For more information on linker magic, see the [`linkme`](https://docs.rs/linkme/latest/linkme/) crate. +/// +/// **IMPORTANT**: Since the resulting rule may not be explicitly referenced, it may be removed by the compiler's dead code elimination. +/// To prevent this, you must ensure that either: +/// 1. codegen-units is set to 1, i.e. in Cargo.toml: +/// ```toml +/// [profile.release] +/// codegen-units = 1 +/// ``` +/// 2. The function is included somewhere else in the code +/// +///
+/// /// Functions must have the signature `fn(&Expr) -> Result`. +/// The created rule will have the same name as the function. /// /// Intermediary static variables are created to allow for the decentralized registry, with the prefix `CONJURE_GEN_`. /// Please ensure that other variable names in the same scope do not conflict with these. +/// +///
+/// +/// For example: +/// ```rust +/// #[register_rule] +/// fn identity(expr: &Expression) -> Result { +/// Ok(expr.clone()) +/// } +/// ``` +/// ... will expand into the following code: +/// ```rust +/// fn identity(expr: &Expression) -> Result { +/// Ok(expr.clone()) +/// } +/// #[::conjure_rules::_dependencies::distributed_slice(::conjure_rules::RULES_DISTRIBUTED_SLICE)] +/// pub static CONJURE_GEN_RULE_IDENTITY: ::conjure_rules::_dependencies::Rule = ::conjure_rules::_dependencies::Rule { +/// name: "identity", +/// application: identity, +/// }; +/// ``` +/// pub fn register_rule(_: TokenStream, item: TokenStream) -> TokenStream { let func = parse_macro_input!(item as ItemFn); let rule_ident = &func.sig.ident; From 87a5e9edc6381e7727a13b47a04d376f33561ed4 Mon Sep 17 00:00:00 2001 From: Felix Date: Thu, 25 Jan 2024 11:08:03 +0000 Subject: [PATCH 27/31] update docs and fix doctests --- crates/conjure_rules/src/lib.rs | 43 +++++++++++++++++++-- crates/conjure_rules_proc_macro/src/lib.rs | 44 +--------------------- 2 files changed, 41 insertions(+), 46 deletions(-) diff --git a/crates/conjure_rules/src/lib.rs b/crates/conjure_rules/src/lib.rs index d7e45fb95..7ce4b1e87 100644 --- a/crates/conjure_rules/src/lib.rs +++ b/crates/conjure_rules/src/lib.rs @@ -37,13 +37,14 @@ pub static RULES_DISTRIBUTED_SLICE: [Rule<'static>]; /// Returns a copied `Vec` of all rules registered with the `register_rule` macro. /// -/// Rules defined in the same file will remain contiguous and in order, but order may not be maintained between files. +/// Rules are not guaranteed to be in any particular order. /// /// # Example /// ```rust -/// use conjure_rules::register_rule; -/// use conjure_oxide::rule::{Rule, RuleApplicationError}; -/// +/// # use conjure_rules::register_rule; +/// # use conjure_core::rule::{Rule, RuleApplicationError}; +/// # use conjure_core::ast::Expression; +/// # /// #[register_rule] /// fn identity(expr: &Expression) -> Result { /// Ok(expr.clone()) @@ -63,4 +64,38 @@ pub fn get_rules() -> Vec> { RULES_DISTRIBUTED_SLICE.to_vec() } +/// This procedural macro registers a decorated function with `conjure_rules`' global registry. +/// It may be used in any downstream crate. For more information on linker magic, see the [`linkme`](https://docs.rs/linkme/latest/linkme/) crate. +/// +/// **IMPORTANT**: Since the resulting rule may not be explicitly referenced, it may be removed by the compiler's dead code elimination. +/// To prevent this, you must ensure that either: +/// 1. codegen-units is set to 1, i.e. in Cargo.toml: +/// ```toml +/// [profile.release] +/// codegen-units = 1 +/// ``` +/// 2. The function is included somewhere else in the code +/// +///
+/// +/// Functions must have the signature `fn(&Expr) -> Result`. +/// The created rule will have the same name as the function. +/// +/// Intermediary static variables are created to allow for the decentralized registry, with the prefix `CONJURE_GEN_`. +/// Please ensure that other variable names in the same scope do not conflict with these. +/// +///
+/// +/// For example: +/// ```rust +/// # use conjure_core::ast::Expression; +/// # use conjure_core::rule::RuleApplicationError; +/// # use conjure_rules::register_rule; +/// # +/// #[register_rule] +/// fn identity(expr: &Expression) -> Result { +/// Ok(expr.clone()) +/// } +/// ``` +#[doc(inline)] pub use conjure_rules_proc_macro::register_rule; diff --git a/crates/conjure_rules_proc_macro/src/lib.rs b/crates/conjure_rules_proc_macro/src/lib.rs index 5bc4880aa..610cf1b4d 100644 --- a/crates/conjure_rules_proc_macro/src/lib.rs +++ b/crates/conjure_rules_proc_macro/src/lib.rs @@ -1,50 +1,10 @@ +//! This is the backend procedural macro crate for `conjure_rules`. USE THAT INSTEAD! + use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, Ident, ItemFn}; -#[doc(hidden)] #[proc_macro_attribute] -/// This procedural macro registers a decorated function with `conjure_rules`' global registry. -/// It may be used in any downstream crate. For more information on linker magic, see the [`linkme`](https://docs.rs/linkme/latest/linkme/) crate. -/// -/// **IMPORTANT**: Since the resulting rule may not be explicitly referenced, it may be removed by the compiler's dead code elimination. -/// To prevent this, you must ensure that either: -/// 1. codegen-units is set to 1, i.e. in Cargo.toml: -/// ```toml -/// [profile.release] -/// codegen-units = 1 -/// ``` -/// 2. The function is included somewhere else in the code -/// -///
-/// -/// Functions must have the signature `fn(&Expr) -> Result`. -/// The created rule will have the same name as the function. -/// -/// Intermediary static variables are created to allow for the decentralized registry, with the prefix `CONJURE_GEN_`. -/// Please ensure that other variable names in the same scope do not conflict with these. -/// -///
-/// -/// For example: -/// ```rust -/// #[register_rule] -/// fn identity(expr: &Expression) -> Result { -/// Ok(expr.clone()) -/// } -/// ``` -/// ... will expand into the following code: -/// ```rust -/// fn identity(expr: &Expression) -> Result { -/// Ok(expr.clone()) -/// } -/// #[::conjure_rules::_dependencies::distributed_slice(::conjure_rules::RULES_DISTRIBUTED_SLICE)] -/// pub static CONJURE_GEN_RULE_IDENTITY: ::conjure_rules::_dependencies::Rule = ::conjure_rules::_dependencies::Rule { -/// name: "identity", -/// application: identity, -/// }; -/// ``` -/// pub fn register_rule(_: TokenStream, item: TokenStream) -> TokenStream { let func = parse_macro_input!(item as ItemFn); let rule_ident = &func.sig.ident; From 5d92794bc14e33dcd3e8ee6d663ff21bcf906424 Mon Sep 17 00:00:00 2001 From: Felix Date: Thu, 25 Jan 2024 14:24:15 +0000 Subject: [PATCH 28/31] add rules and application tests --- conjure_oxide/src/rules/mod.rs | 54 +++++++++++++++++++++-- conjure_oxide/tests/rewrite_tests.rs | 64 +++++++++++++++++++++++++++- crates/conjure_rules/src/lib.rs | 4 ++ 3 files changed, 118 insertions(+), 4 deletions(-) diff --git a/conjure_oxide/src/rules/mod.rs b/conjure_oxide/src/rules/mod.rs index 4d4702c64..40bd82251 100644 --- a/conjure_oxide/src/rules/mod.rs +++ b/conjure_oxide/src/rules/mod.rs @@ -1,7 +1,55 @@ -use conjure_core::{ast::Expression, rule::RuleApplicationError}; +use conjure_core::{ast::Expression as Expr, rule::RuleApplicationError}; use conjure_rules::register_rule; +// #[register_rule] +// fn identity(expr: &Expr) -> Result { +// Ok(expr.clone()) +// } + +#[register_rule] +fn sum_constants(expr: &Expr) -> Result { + match expr { + Expr::Sum(exprs) => { + let mut sum = 0; + let mut new_exprs = Vec::new(); + let mut changed = false; + for e in exprs { + match e { + Expr::ConstantInt(i) => { + sum += i; + changed = true; + } + _ => new_exprs.push(e.clone()), + } + } + if !changed { + return Err(RuleApplicationError::RuleNotApplicable); + } + new_exprs.push(Expr::ConstantInt(sum)); + Ok(Expr::Sum(new_exprs)) // Let other rules handle only one Expr being contained in the sum + } + _ => Err(RuleApplicationError::RuleNotApplicable), + } +} + +#[register_rule] +fn unwrap_sum(expr: &Expr) -> Result { + match expr { + Expr::Sum(exprs) if (exprs.len() == 1) => Ok(exprs[0].clone()), + _ => Err(RuleApplicationError::RuleNotApplicable), + } +} + #[register_rule] -fn identity(expr: &Expression) -> Result { - Ok(expr.clone()) +fn flatten_sum_geq(expr: &Expr) -> Result { + match expr { + Expr::Geq(a, b) => { + let exprs = match a.as_ref() { + Expr::Sum(exprs) => Ok(exprs), + _ => Err(RuleApplicationError::RuleNotApplicable), + }?; + Ok(Expr::SumGeq(exprs.clone(), b.clone())) + } + _ => Err(RuleApplicationError::RuleNotApplicable), + } } diff --git a/conjure_oxide/tests/rewrite_tests.rs b/conjure_oxide/tests/rewrite_tests.rs index 0061c6efe..95404a4bc 100644 --- a/conjure_oxide/tests/rewrite_tests.rs +++ b/conjure_oxide/tests/rewrite_tests.rs @@ -3,10 +3,11 @@ use core::panic; use conjure_oxide::ast::*; +use conjure_rules::{get_rule_by_name, get_rules}; #[test] fn rules_present() { - let rules = conjure_rules::get_rules(); + let rules = get_rules(); assert!(rules.len() > 0); } @@ -97,3 +98,64 @@ fn simplify_expression(expr: Expression) -> Expression { _ => expr, } } + +#[test] +fn rule_sum_constants() { + let sum_constants = get_rule_by_name("sum_constants").unwrap(); + let unwrap_sum = get_rule_by_name("unwrap_sum").unwrap(); + + let mut expr = Expression::Sum(vec![ + Expression::ConstantInt(1), + Expression::ConstantInt(2), + Expression::ConstantInt(3), + ]); + + expr = sum_constants.apply(&expr).unwrap(); + expr = unwrap_sum.apply(&expr).unwrap(); + + assert_eq!(expr, Expression::ConstantInt(6)); +} + +#[test] +fn rule_sum_mixed() { + let sum_constants = get_rule_by_name("sum_constants").unwrap(); + + let mut expr = Expression::Sum(vec![ + Expression::ConstantInt(1), + Expression::ConstantInt(2), + Expression::Reference(Name::UserName(String::from("a"))), + ]); + + expr = sum_constants.apply(&expr).unwrap(); + + assert_eq!( + expr, + Expression::Sum(vec![ + Expression::Reference(Name::UserName(String::from("a"))), + Expression::ConstantInt(3), + ]) + ); +} + +#[test] +fn rule_sum_geq() { + let flatten_sum_geq = get_rule_by_name("flatten_sum_geq").unwrap(); + + let mut expr = Expression::Geq( + Box::new(Expression::Sum(vec![ + Expression::ConstantInt(1), + Expression::ConstantInt(2), + ])), + Box::new(Expression::ConstantInt(3)), + ); + + expr = flatten_sum_geq.apply(&expr).unwrap(); + + assert_eq!( + expr, + Expression::SumGeq( + vec![Expression::ConstantInt(1), Expression::ConstantInt(2),], + Box::new(Expression::ConstantInt(3)) + ) + ); +} diff --git a/crates/conjure_rules/src/lib.rs b/crates/conjure_rules/src/lib.rs index 7ce4b1e87..a3064653d 100644 --- a/crates/conjure_rules/src/lib.rs +++ b/crates/conjure_rules/src/lib.rs @@ -64,6 +64,10 @@ pub fn get_rules() -> Vec> { RULES_DISTRIBUTED_SLICE.to_vec() } +pub fn get_rule_by_name(name: &str) -> Option> { + get_rules().iter().find(|rule| rule.name == name).cloned() +} + /// This procedural macro registers a decorated function with `conjure_rules`' global registry. /// It may be used in any downstream crate. For more information on linker magic, see the [`linkme`](https://docs.rs/linkme/latest/linkme/) crate. /// From 2f3d27261604b5f1098c4ed15b221ff75213a035 Mon Sep 17 00:00:00 2001 From: Felix Date: Thu, 25 Jan 2024 16:50:00 +0000 Subject: [PATCH 29/31] add manual rewrite test --- conjure_oxide/src/lib.rs | 2 +- conjure_oxide/src/main.rs | 8 ++- conjure_oxide/src/rules/mod.rs | 26 +++++++ conjure_oxide/src/solvers/minion.rs | 5 +- conjure_oxide/tests/rewrite_tests.rs | 103 ++++++++++++++++++++++++++- 5 files changed, 139 insertions(+), 5 deletions(-) diff --git a/conjure_oxide/src/lib.rs b/conjure_oxide/src/lib.rs index 022ac9106..69c2e0bb0 100644 --- a/conjure_oxide/src/lib.rs +++ b/conjure_oxide/src/lib.rs @@ -2,7 +2,7 @@ pub mod error; pub mod find_conjure; pub mod parse; mod rules; -mod solvers; +pub mod solvers; pub use conjure_core::ast; // re-export core::ast as conjure_oxide::ast pub use conjure_core::ast::Model; // rexport core::ast::Model as conjure_oxide::Model diff --git a/conjure_oxide/src/main.rs b/conjure_oxide/src/main.rs index 0699ff379..e382740ce 100644 --- a/conjure_oxide/src/main.rs +++ b/conjure_oxide/src/main.rs @@ -19,7 +19,13 @@ struct Cli { } pub fn main() -> AnyhowResult<()> { - println!("Rules: {:?}", conjure_rules::get_rules()); + println!( + "Rules: {:?}", + conjure_rules::get_rules() + .iter() + .map(|r| r.name) + .collect::>() + ); let cli = Cli::parse(); println!("Input file: {}", cli.input_file.display()); diff --git a/conjure_oxide/src/rules/mod.rs b/conjure_oxide/src/rules/mod.rs index 40bd82251..934f99200 100644 --- a/conjure_oxide/src/rules/mod.rs +++ b/conjure_oxide/src/rules/mod.rs @@ -53,3 +53,29 @@ fn flatten_sum_geq(expr: &Expr) -> Result { _ => Err(RuleApplicationError::RuleNotApplicable), } } + +#[register_rule] +fn sum_eq_to_sumleq(expr: &Expr) -> Result { + match expr { + Expr::Eq(a, b) => { + let exprs = match a.as_ref() { + Expr::Sum(exprs) => Ok(exprs), + _ => Err(RuleApplicationError::RuleNotApplicable), + }?; + Ok(Expr::SumLeq(exprs.clone(), b.clone())) + } + _ => Err(RuleApplicationError::RuleNotApplicable), + } +} + +#[register_rule] +fn lt_to_ineq(expr: &Expr) -> Result { + match expr { + Expr::Lt(a, b) => Ok(Expr::Ineq( + a.clone(), + b.clone(), + Box::new(Expr::ConstantInt(-1)), + )), + _ => Err(RuleApplicationError::RuleNotApplicable), + } +} diff --git a/conjure_oxide/src/solvers/minion.rs b/conjure_oxide/src/solvers/minion.rs index f3eea6095..76ab90414 100644 --- a/conjure_oxide/src/solvers/minion.rs +++ b/conjure_oxide/src/solvers/minion.rs @@ -7,9 +7,10 @@ use crate::ast::{ DecisionVariable, Domain as ConjureDomain, Expression as ConjureExpression, Model as ConjureModel, Name as ConjureName, Range as ConjureRange, }; +pub use minion_rs::ast::Model as MinionModel; use minion_rs::ast::{ - Constant as MinionConstant, Constraint as MinionConstraint, Model as MinionModel, - Var as MinionVar, VarDomain as MinionDomain, + Constant as MinionConstant, Constraint as MinionConstraint, Var as MinionVar, + VarDomain as MinionDomain, }; const SOLVER: Solver = Solver::Minion; diff --git a/conjure_oxide/tests/rewrite_tests.rs b/conjure_oxide/tests/rewrite_tests.rs index 95404a4bc..e59dedd09 100644 --- a/conjure_oxide/tests/rewrite_tests.rs +++ b/conjure_oxide/tests/rewrite_tests.rs @@ -1,9 +1,14 @@ // Tests for rewriting/simplifying parts of the AST use core::panic; +use std::collections::HashMap; -use conjure_oxide::ast::*; +use conjure_oxide::{ + ast::*, + solvers::{minion, FromConjureModel}, +}; use conjure_rules::{get_rule_by_name, get_rules}; +use minion_rs::ast::{Constant, VarName}; #[test] fn rules_present() { @@ -159,3 +164,99 @@ fn rule_sum_geq() { ) ); } + +fn callback(solution: HashMap) -> bool { + println!("Solution: {:?}", solution); + false +} + +/// +/// Reduce and solve: +/// ```text +/// find a,b,c : int(1..3) +/// such that a + b + c = 2 + 3 - 1 +/// such that a < b +/// ``` +#[test] +fn reduce_solve_xyz() { + println!("Rules: {:?}", conjure_rules::get_rules()); + let sum_constants = get_rule_by_name("sum_constants").unwrap(); + let unwrap_sum = get_rule_by_name("unwrap_sum").unwrap(); + let lt_to_ineq = get_rule_by_name("lt_to_ineq").unwrap(); + let sum_eq_to_sumleq = get_rule_by_name("sum_eq_to_sumleq").unwrap(); + + // 2 + 3 - 1 + let mut expr1 = Expression::Sum(vec![ + Expression::ConstantInt(2), + Expression::ConstantInt(3), + Expression::ConstantInt(-1), + ]); + + expr1 = sum_constants.apply(&expr1).unwrap(); + expr1 = unwrap_sum.apply(&expr1).unwrap(); + assert_eq!(expr1, Expression::ConstantInt(4)); + + // a + b + c = 4 + expr1 = Expression::Eq( + Box::new(Expression::Sum(vec![ + Expression::Reference(Name::UserName(String::from("a"))), + Expression::Reference(Name::UserName(String::from("b"))), + Expression::Reference(Name::UserName(String::from("c"))), + ])), + Box::new(expr1), + ); + expr1 = sum_eq_to_sumleq.apply(&expr1).unwrap(); + assert_eq!( + expr1, + Expression::SumLeq( + vec![ + Expression::Reference(Name::UserName(String::from("a"))), + Expression::Reference(Name::UserName(String::from("b"))), + Expression::Reference(Name::UserName(String::from("c"))), + ], + Box::new(Expression::ConstantInt(4)) + ) + ); + + // a < b + let mut expr2 = Expression::Lt( + Box::new(Expression::Reference(Name::UserName(String::from("a")))), + Box::new(Expression::Reference(Name::UserName(String::from("b")))), + ); + expr2 = lt_to_ineq.apply(&expr2).unwrap(); + assert_eq!( + expr2, + Expression::Ineq( + Box::new(Expression::Reference(Name::UserName(String::from("a")))), + Box::new(Expression::Reference(Name::UserName(String::from("b")))), + Box::new(Expression::ConstantInt(-1)) + ) + ); + + let mut model = Model { + variables: HashMap::new(), + constraints: vec![expr1, expr2], + }; + model.variables.insert( + Name::UserName(String::from("a")), + DecisionVariable { + domain: Domain::IntDomain(vec![Range::Bounded(1, 3)]), + }, + ); + model.variables.insert( + Name::UserName(String::from("b")), + DecisionVariable { + domain: Domain::IntDomain(vec![Range::Bounded(1, 3)]), + }, + ); + model.variables.insert( + Name::UserName(String::from("c")), + DecisionVariable { + domain: Domain::IntDomain(vec![Range::Bounded(1, 3)]), + }, + ); + + let minion_model = conjure_oxide::solvers::minion::MinionModel::from_conjure(model).unwrap(); + + minion_rs::run_minion(minion_model, callback).unwrap(); +} From e5834ea3910090607b7d5131487310d8c8a4b2ed Mon Sep 17 00:00:00 2001 From: Niklas Dewally Date: Mon, 22 Jan 2024 14:26:08 +0000 Subject: [PATCH 30/31] Make chuffed-rs non-default member of workspace. Chuffed-rs does not compile on lab machines. Making it non default means that cargo test / cargo building the workspace will now succeed on the school lab machines. --- Cargo.toml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 834320ce1..80bf72b36 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,13 @@ [workspace] resolver = "2" + +default-members = [ + "conjure_oxide", + "crates/conjure_core", + "solvers/kissat", + "solvers/minion", +] + members = [ "conjure_oxide", "crates/conjure_core", From 26910302b10d9dfeeb97067d54995a3cc457fac1 Mon Sep 17 00:00:00 2001 From: Felix Date: Fri, 26 Jan 2024 12:08:39 +0000 Subject: [PATCH 31/31] correct sum_leq rule --- conjure_oxide/src/rules/mod.rs | 4 ++-- conjure_oxide/tests/rewrite_tests.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/conjure_oxide/src/rules/mod.rs b/conjure_oxide/src/rules/mod.rs index 934f99200..09f07fe44 100644 --- a/conjure_oxide/src/rules/mod.rs +++ b/conjure_oxide/src/rules/mod.rs @@ -55,9 +55,9 @@ fn flatten_sum_geq(expr: &Expr) -> Result { } #[register_rule] -fn sum_eq_to_sumleq(expr: &Expr) -> Result { +fn sum_leq_to_sumleq(expr: &Expr) -> Result { match expr { - Expr::Eq(a, b) => { + Expr::Leq(a, b) => { let exprs = match a.as_ref() { Expr::Sum(exprs) => Ok(exprs), _ => Err(RuleApplicationError::RuleNotApplicable), diff --git a/conjure_oxide/tests/rewrite_tests.rs b/conjure_oxide/tests/rewrite_tests.rs index e59dedd09..865bb5d56 100644 --- a/conjure_oxide/tests/rewrite_tests.rs +++ b/conjure_oxide/tests/rewrite_tests.rs @@ -174,7 +174,7 @@ fn callback(solution: HashMap) -> bool { /// Reduce and solve: /// ```text /// find a,b,c : int(1..3) -/// such that a + b + c = 2 + 3 - 1 +/// such that a + b + c <= 2 + 3 - 1 /// such that a < b /// ``` #[test] @@ -183,7 +183,7 @@ fn reduce_solve_xyz() { let sum_constants = get_rule_by_name("sum_constants").unwrap(); let unwrap_sum = get_rule_by_name("unwrap_sum").unwrap(); let lt_to_ineq = get_rule_by_name("lt_to_ineq").unwrap(); - let sum_eq_to_sumleq = get_rule_by_name("sum_eq_to_sumleq").unwrap(); + let sum_leq_to_sumleq = get_rule_by_name("sum_leq_to_sumleq").unwrap(); // 2 + 3 - 1 let mut expr1 = Expression::Sum(vec![ @@ -197,7 +197,7 @@ fn reduce_solve_xyz() { assert_eq!(expr1, Expression::ConstantInt(4)); // a + b + c = 4 - expr1 = Expression::Eq( + expr1 = Expression::Leq( Box::new(Expression::Sum(vec![ Expression::Reference(Name::UserName(String::from("a"))), Expression::Reference(Name::UserName(String::from("b"))), @@ -205,7 +205,7 @@ fn reduce_solve_xyz() { ])), Box::new(expr1), ); - expr1 = sum_eq_to_sumleq.apply(&expr1).unwrap(); + expr1 = sum_leq_to_sumleq.apply(&expr1).unwrap(); assert_eq!( expr1, Expression::SumLeq(