From 2e0253745dd19d46c83729f571d6b4c0a0f21c49 Mon Sep 17 00:00:00 2001 From: niklasdewally Date: Sat, 30 Mar 2024 15:05:22 +0000 Subject: [PATCH] Actions: Code Coverage for 86f194547b9068fafb5ae7ae6dfb328383c11062 --- .../badges/flat.svg | 23 + .../badges/flat_square.svg | 13 + .../badges/for_the_badge.svg | 13 + .../badges/plastic.svg | 25 + .../badges/social.svg | 27 + .../conjure_oxide/src/find_conjure.rs.html | 1049 + .../conjure_oxide/src/index.html | 74 + .../conjure_oxide/src/utils/conjure.rs.html | 1769 ++ .../conjure_oxide/src/utils/index.html | 146 + .../conjure_oxide/src/utils/json.rs.html | 1305 ++ .../conjure_oxide/src/utils/misc.rs.html | 217 + .../conjure_oxide/src/utils/testing.rs.html | 3001 +++ .../tests/generated_tests.rs.html | 1561 ++ .../conjure_oxide/tests/index.html | 122 + .../conjure_oxide/tests/model_tests.rs.html | 537 + .../conjure_oxide/tests/rewrite_tests.rs.html | 18233 ++++++++++++++++ .../coverage.json | 1 + .../conjure_core/src/ast/constants.rs.html | 665 + .../conjure_core/src/ast/domains.rs.html | 1353 ++ .../conjure_core/src/ast/expressions.rs.html | 3513 +++ .../crates/conjure_core/src/ast/index.html | 170 + .../conjure_core/src/ast/symbol_table.rs.html | 409 + .../conjure_core/src/ast/variables.rs.html | 665 + .../crates/conjure_core/src/context.rs.html | 1433 ++ .../crates/conjure_core/src/error.rs.html | 377 + .../crates/conjure_core/src/index.html | 146 + .../crates/conjure_core/src/metadata.rs.html | 665 + .../crates/conjure_core/src/model.rs.html | 1657 ++ .../src/parse/example_models.rs.html | 1769 ++ .../crates/conjure_core/src/parse/index.html | 98 + .../src/parse/parse_model.rs.html | 5065 +++++ .../conjure_core/src/rule_engine/index.html | 170 + .../conjure_core/src/rule_engine/mod.rs.html | 3657 ++++ .../src/rule_engine/resolve_rules.rs.html | 2505 +++ .../src/rule_engine/rewrite.rs.html | 2009 ++ .../conjure_core/src/rule_engine/rule.rs.html | 2313 ++ .../src/rule_engine/rule_set.rs.html | 2809 +++ .../conjure_core/src/rules/base.rs.html | 8425 +++++++ .../crates/conjure_core/src/rules/cnf.rs.html | 1001 + .../conjure_core/src/rules/constant.rs.html | 2041 ++ .../crates/conjure_core/src/rules/index.html | 146 + .../conjure_core/src/rules/minion.rs.html | 4793 ++++ .../src/solver/adaptors/index.html | 122 + .../src/solver/adaptors/kissat.rs.html | 1049 + .../src/solver/adaptors/minion.rs.html | 5625 +++++ .../src/solver/adaptors/sat_common.rs.html | 5225 +++++ .../crates/conjure_core/src/solver/index.html | 98 + .../conjure_core/src/solver/mod.rs.html | 6937 ++++++ .../src/solver/model_modifier.rs.html | 905 + .../crates/conjure_core/src/stats/index.html | 98 + .../crates/conjure_core/src/stats/mod.rs.html | 425 + .../src/stats/solver_stats.rs.html | 665 + .../crates/conjure_macros/src/index.html | 74 + .../crates/conjure_macros/src/lib.rs.html | 2937 +++ .../enum_compatability_macro/src/index.html | 74 + .../enum_compatability_macro/src/lib.rs.html | 3193 +++ .../crates/uniplate/src/biplate.rs.html | 2361 ++ .../crates/uniplate/src/index.html | 146 + .../crates/uniplate/src/lib.rs.html | 1881 ++ .../uniplate/src/test_common/index.html | 74 + .../uniplate/src/test_common/paper.rs.html | 1033 + .../crates/uniplate/src/tree.rs.html | 2409 ++ .../crates/uniplate/src/uniplate.rs.html | 2409 ++ .../uniplate/tests/expr_stmt_manual.rs.html | 7225 ++++++ .../crates/uniplate/tests/index.html | 74 + .../crates/uniplate_derive/src/index.html | 74 + .../crates/uniplate_derive/src/lib.rs.html | 3081 +++ .../src/utils/generate.rs.html | 3001 +++ .../uniplate_derive/src/utils/index.html | 98 + .../uniplate_derive/src/utils/parse.rs.html | 2169 ++ .../crates/uniplate_derive/tests/index.html | 74 + .../uniplate_derive/tests/macro_tests.rs.html | 3945 ++++ .../doc-coverage.json | 9 + .../doc-coverage.txt | 104 + .../index.html | 626 + .../lcov.info | 10929 +++++++++ .../prnumber | 1 + .../solvers/chuffed/src/index.html | 74 + .../solvers/chuffed/src/lib.rs.html | 1177 + .../chuffed/tests/chuffed_basic_run.rs.html | 1113 + .../chuffed/tests/chuffed_cpp_run.rs.html | 265 + .../solvers/chuffed/tests/dummy_test.rs.html | 105 + .../solvers/chuffed/tests/index.html | 122 + .../solvers/kissat/src/index.html | 74 + .../solvers/kissat/src/lib.rs.html | 537 + .../solvers/minion/src/ast.rs.html | 3257 +++ .../solvers/minion/src/error.rs.html | 905 + .../solvers/minion/src/ffi.rs.html | 1721 ++ .../solvers/minion/src/index.html | 194 + .../solvers/minion/src/lib.rs.html | 1897 ++ .../solvers/minion/src/run.rs.html | 12217 +++++++++++ .../solvers/minion/src/scoped_ptr.rs.html | 473 + .../solvers/minion/tests/index.html | 74 + .../tests/test_watchedor_reifyimply_1.rs.html | 1033 + 94 files changed, 170358 insertions(+) create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/badges/flat.svg create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/badges/flat_square.svg create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/badges/for_the_badge.svg create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/badges/plastic.svg create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/badges/social.svg create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/find_conjure.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/utils/conjure.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/utils/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/utils/json.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/utils/misc.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/utils/testing.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/tests/generated_tests.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/tests/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/tests/model_tests.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/tests/rewrite_tests.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/coverage.json create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/constants.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/domains.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/expressions.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/symbol_table.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/variables.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/context.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/error.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/metadata.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/model.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/parse/example_models.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/parse/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/parse/parse_model.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/mod.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/resolve_rules.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/rewrite.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/rule.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/rule_set.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rules/base.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rules/cnf.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rules/constant.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rules/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rules/minion.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/adaptors/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/adaptors/kissat.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/adaptors/minion.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/adaptors/sat_common.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/mod.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/model_modifier.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/stats/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/stats/mod.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/stats/solver_stats.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_macros/src/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_macros/src/lib.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/enum_compatability_macro/src/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/enum_compatability_macro/src/lib.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/biplate.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/lib.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/test_common/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/test_common/paper.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/tree.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/uniplate.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/tests/expr_stmt_manual.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/tests/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/src/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/src/lib.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/src/utils/generate.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/src/utils/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/src/utils/parse.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/tests/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/tests/macro_tests.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/doc-coverage.json create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/doc-coverage.txt create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/lcov.info create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/prnumber create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/src/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/src/lib.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/tests/chuffed_basic_run.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/tests/chuffed_cpp_run.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/tests/dummy_test.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/tests/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/kissat/src/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/kissat/src/lib.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/ast.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/error.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/ffi.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/lib.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/run.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/scoped_ptr.rs.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/tests/index.html create mode 100644 coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/tests/test_watchedor_reifyimply_1.rs.html diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/badges/flat.svg b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/badges/flat.svg new file mode 100644 index 0000000000..2e4a6c6166 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/badges/flat.svg @@ -0,0 +1,23 @@ + + coverage: 73% + + + + + + + + + + + + + + + coverage + + 73% + + + \ No newline at end of file diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/badges/flat_square.svg b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/badges/flat_square.svg new file mode 100644 index 0000000000..134d30f0cd --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/badges/flat_square.svg @@ -0,0 +1,13 @@ + + coverage: 73% + + + + + + coverage + 73% + + + \ No newline at end of file diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/badges/for_the_badge.svg b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/badges/for_the_badge.svg new file mode 100644 index 0000000000..1d7a89c2e5 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/badges/for_the_badge.svg @@ -0,0 +1,13 @@ + + COVERAGE: 73% + + + + + + COVERAGE + 73% + + + \ No newline at end of file diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/badges/plastic.svg b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/badges/plastic.svg new file mode 100644 index 0000000000..0fe3efb4bb --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/badges/plastic.svg @@ -0,0 +1,25 @@ + + coverage: 73% + + + + + + + + + + + + + + + + + coverage + + 73% + + + \ No newline at end of file diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/badges/social.svg b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/badges/social.svg new file mode 100644 index 0000000000..1bed54968e --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/badges/social.svg @@ -0,0 +1,27 @@ + + Coverage: 73% + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/find_conjure.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/find_conjure.rs.html new file mode 100644 index 0000000000..e9cfea639c --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/find_conjure.rs.html @@ -0,0 +1,1049 @@ + + + + + Grcov report - find_conjure.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use anyhow::{anyhow, bail, Result};
+
+
+
+ 2 +
+
+ +
+
+
use versions::Versioning;
+
+
+
+ 3 +
+
+ +
+
+

+            
+
+
+ 4 +
+
+ +
+
+
const CONJURE_MIN_VERSION: &str = "2.5.1";
+
+
+
+ 5 +
+
+ +
+
+
const CORRECT_FIRST_LINE: &str = "Conjure: The Automated Constraint Modelling Tool";
+
+
+
+ 6 +
+
+ +
+
+

+            
+
+
+ 7 +
+
+ +
+
+
/// Checks if the conjure executable is present in PATH and if it is the correct version.
+
+
+
+ 8 +
+
+ +
+
+
/// Returns () on success and an error on failure.
+
+
+
+ 9 +
+
+ 5 +
+
+
pub fn conjure_executable() -> Result<()> {
+
+
+
+ 10 +
+
+ 5 +
+
+
    let mut cmd = std::process::Command::new("conjure");
+
+
+
+ 11 +
+
+ 5 +
+
+
    let output = cmd.arg("--version").output()?;
+
+
+
+ 12 +
+
+ 5 +
+
+
    let stdout = String::from_utf8(output.stdout)?;
+
+
+
+ 13 +
+
+ 5 +
+
+
    let stderr = String::from_utf8(output.stderr)?;
+
+
+
+ 14 +
+
+ +
+
+

+            
+
+
+ 15 +
+
+ 5 +
+
+
    if !stderr.is_empty() {
+
+
+
+ 16 +
+
+ +
+
+
        bail!("'conjure' results in error: ".to_string() + &stderr);
+
+
+
+ 17 +
+
+ 5 +
+
+
    }
+
+
+
+ 18 +
+
+ 5 +
+
+
    let first = stdout
+
+
+
+ 19 +
+
+ 5 +
+
+
        .lines()
+
+
+
+ 20 +
+
+ 5 +
+
+
        .next()
+
+
+
+ 21 +
+
+ 5 +
+
+
        .ok_or(anyhow!("Could not read stdout"))?;
+
+
+
+ 22 +
+
+ 5 +
+
+
    if first != CORRECT_FIRST_LINE {
+
+
+
+ 23 +
+
+ +
+
+
        let path = std::env::var("PATH")?;
+
+
+
+ 24 +
+
+ +
+
+
        let paths = std::env::split_paths(&path);
+
+
+
+ 25 +
+
+ +
+
+
        let num_conjures = paths.filter(|path| path.join("conjure").exists()).count();
+
+
+
+ 26 +
+
+ +
+
+
        if num_conjures > 1 {
+
+
+
+ 27 +
+
+ +
+
+
            bail!(
+
+
+
+ 28 +
+
+ +
+
+
                "Conjure may be present in PATH after a conflicting name. \
+
+
+
+ 29 +
+
+ +
+
+
            Make sure to prepend the correct path to Conjure to PATH."
+
+
+
+ 30 +
+
+ +
+
+
            )
+
+
+
+ 31 +
+
+ +
+
+
        } else {
+
+
+
+ 32 +
+
+ +
+
+
            bail!("The correct Conjure executable is not present in PATH.")
+
+
+
+ 33 +
+
+ +
+
+
        }
+
+
+
+ 34 +
+
+ 5 +
+
+
    }
+
+
+
+ 35 +
+
+ 5 +
+
+
    let version_line = stdout
+
+
+
+ 36 +
+
+ 5 +
+
+
        .lines()
+
+
+
+ 37 +
+
+ 5 +
+
+
        .nth(1)
+
+
+
+ 38 +
+
+ 5 +
+
+
        .ok_or(anyhow!("Could not read Conjure's stdout"))?;
+
+
+
+ 39 +
+
+ +
+
+

+            
+
+
+ 40 +
+
+ 5 +
+
+
    let version = match version_line.strip_prefix("Release version ") {
+
+
+
+ 41 +
+
+ 5 +
+
+
        Some(v) => Ok(v),
+
+
+
+ 42 +
+
+ +
+
+
        None => match version_line.strip_prefix("Conjure v") {
+
+
+
+ 43 +
+
+ +
+
+
            // New format: Conjure v2.5.1 (Repository version ...)
+
+
+
+ 44 +
+
+ +
+
+
            Some(v) => v.split_whitespace().next().ok_or(anyhow!(
+
+
+
+ 45 +
+
+ +
+
+
                "Could not read Conjure's version from: {}",
+
+
+
+ 46 +
+
+ +
+
+
                version_line
+
+
+
+ 47 +
+
+ +
+
+
            )),
+
+
+
+ 48 +
+
+ +
+
+
            None => Err(anyhow!(
+
+
+
+ 49 +
+
+ +
+
+
                "Could not read Conjure's version from: {}",
+
+
+
+ 50 +
+
+ +
+
+
                version_line
+
+
+
+ 51 +
+
+ +
+
+
            )),
+
+
+
+ 52 +
+
+ +
+
+
        },
+
+
+
+ 53 +
+
+ +
+
+
    }?;
+
+
+
+ 54 +
+
+ +
+
+

+            
+
+
+ 55 +
+
+ 5 +
+
+
    if Versioning::new(version) < Versioning::new(CONJURE_MIN_VERSION) {
+
+
+
+ 56 +
+
+ +
+
+
        bail!(
+
+
+
+ 57 +
+
+ +
+
+
            "Conjure version is too old (< {}): {}",
+
+
+
+ 58 +
+
+ +
+
+
            CONJURE_MIN_VERSION,
+
+
+
+ 59 +
+
+ +
+
+
            version
+
+
+
+ 60 +
+
+ +
+
+
        );
+
+
+
+ 61 +
+
+ 5 +
+
+
    }
+
+
+
+ 62 +
+
+ 5 +
+
+
    Ok(())
+
+
+
+ 63 +
+
+ 5 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/index.html new file mode 100644 index 0000000000..ca22ba029a --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/index.html @@ -0,0 +1,74 @@ + + + + + Grcov report - conjure_oxide/src + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
find_conjure.rs + + 47.92% + + + 47.92% + + 23 / 48 + 16.67%1 / 6
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/utils/conjure.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/utils/conjure.rs.html new file mode 100644 index 0000000000..780fbfbad6 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/utils/conjure.rs.html @@ -0,0 +1,1769 @@ + + + + + Grcov report - conjure.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use std::collections::HashMap;
+
+
+
+ 2 +
+
+ +
+
+
use std::sync::{Arc, Mutex, RwLock};
+
+
+
+ 3 +
+
+ +
+
+

+            
+
+
+ 4 +
+
+ +
+
+
use conjure_core::context::Context;
+
+
+
+ 5 +
+
+ +
+
+
use serde_json::{Map, Value as JsonValue};
+
+
+
+ 6 +
+
+ +
+
+
use thiserror::Error as ThisError;
+
+
+
+ 7 +
+
+ +
+
+

+            
+
+
+ 8 +
+
+ +
+
+
use crate::ast::{Constant, Name};
+
+
+
+ 9 +
+
+ +
+
+
use crate::model_from_json;
+
+
+
+ 10 +
+
+ +
+
+
use crate::solver::adaptors::Minion;
+
+
+
+ 11 +
+
+ +
+
+
use crate::solver::Solver;
+
+
+
+ 12 +
+
+ +
+
+
use crate::utils::json::sort_json_object;
+
+
+
+ 13 +
+
+ +
+
+
use crate::Error as ParseErr;
+
+
+
+ 14 +
+
+ +
+
+
use crate::Model;
+
+
+
+ 15 +
+
+ +
+
+

+            
+
+
+ 16 +
+
+ +
+
+
#[derive(Debug, ThisError)]
+
+
+
+ 17 +
+
+ +
+
+
pub enum EssenceParseError {
+
+
+
+ 18 +
+
+ +
+
+
    #[error("Error running conjure pretty: {0}")]
+
+
+
+ 19 +
+
+ +
+
+
    ConjurePrettyError(String),
+
+
+
+ 20 +
+
+ +
+
+
    #[error("Error parsing essence file: {0}")]
+
+
+
+ 21 +
+
+ +
+
+
    ParseError(ParseErr),
+
+
+
+ 22 +
+
+ +
+
+
}
+
+
+
+ 23 +
+
+ +
+
+

+            
+
+
+ 24 +
+
+ +
+
+
impl From<ParseErr> for EssenceParseError {
+
+
+
+ 25 +
+
+ +
+
+
    fn from(e: ParseErr) -> Self {
+
+
+
+ 26 +
+
+ +
+
+
        EssenceParseError::ParseError(e)
+
+
+
+ 27 +
+
+ +
+
+
    }
+
+
+
+ 28 +
+
+ +
+
+
}
+
+
+
+ 29 +
+
+ +
+
+

+            
+
+
+ 30 +
+
+ 45 +
+
+
pub fn parse_essence_file(
+
+
+
+ 31 +
+
+ 45 +
+
+
    path: &str,
+
+
+
+ 32 +
+
+ 45 +
+
+
    filename: &str,
+
+
+
+ 33 +
+
+ 45 +
+
+
    context: Arc<RwLock<Context<'static>>>,
+
+
+
+ 34 +
+
+ 45 +
+
+
) -> Result<Model, EssenceParseError> {
+
+
+
+ 35 +
+
+ 45 +
+
+
    let mut cmd = std::process::Command::new("conjure");
+
+
+
+ 36 +
+
+ 45 +
+
+
    let output = match cmd
+
+
+
+ 37 +
+
+ 45 +
+
+
        .arg("pretty")
+
+
+
+ 38 +
+
+ 45 +
+
+
        .arg("--output-format=astjson")
+
+
+
+ 39 +
+
+ 45 +
+
+
        .arg(format!("{path}/{filename}.essence"))
+
+
+
+ 40 +
+
+ 45 +
+
+
        .output()
+
+
+
+ 41 +
+
+ +
+
+
    {
+
+
+
+ 42 +
+
+ 45 +
+
+
        Ok(output) => output,
+
+
+
+ 43 +
+
+ +
+
+
        Err(e) => return Err(EssenceParseError::ConjurePrettyError(e.to_string())),
+
+
+
+ 44 +
+
+ +
+
+
    };
+
+
+
+ 45 +
+
+ +
+
+

+            
+
+
+ 46 +
+
+ 45 +
+
+
    if !output.status.success() {
+
+
+
+ 47 +
+
+ +
+
+
        let stderr_string = String::from_utf8(output.stderr)
+
+
+
+ 48 +
+
+ +
+
+
            .unwrap_or("stderr is not a valid UTF-8 string".to_string());
+
+
+
+ 49 +
+
+ +
+
+
        return Err(EssenceParseError::ConjurePrettyError(stderr_string));
+
+
+
+ 50 +
+
+ 45 +
+
+
    }
+
+
+
+ 51 +
+
+ +
+
+

+            
+
+
+ 52 +
+
+ 45 +
+
+
    let astjson = match String::from_utf8(output.stdout) {
+
+
+
+ 53 +
+
+ 45 +
+
+
        Ok(astjson) => astjson,
+
+
+
+ 54 +
+
+ +
+
+
        Err(e) => {
+
+
+
+ 55 +
+
+ +
+
+
            return Err(EssenceParseError::ConjurePrettyError(format!(
+
+
+
+ 56 +
+
+ +
+
+
                "Error parsing output from conjure: {:#?}",
+
+
+
+ 57 +
+
+ +
+
+
                e
+
+
+
+ 58 +
+
+ +
+
+
            )))
+
+
+
+ 59 +
+
+ +
+
+
        }
+
+
+
+ 60 +
+
+ +
+
+
    };
+
+
+
+ 61 +
+
+ +
+
+

+            
+
+
+ 62 +
+
+ 45 +
+
+
    let parsed_model = model_from_json(&astjson, context)?;
+
+
+
+ 63 +
+
+ 45 +
+
+
    Ok(parsed_model)
+
+
+
+ 64 +
+
+ 45 +
+
+
}
+
+
+
+ 65 +
+
+ +
+
+

+            
+
+
+ 66 +
+
+ 45 +
+
+
pub fn get_minion_solutions(model: Model) -> Result<Vec<HashMap<Name, Constant>>, anyhow::Error> {
+
+
+
+ 67 +
+
+ 45 +
+
+
    let solver = Solver::new(Minion::new());
+
+
+
+ 68 +
+
+ 45 +
+
+

+            
+
+
+ 69 +
+
+ 45 +
+
+
    println!("Building Minion model...");
+
+
+
+ 70 +
+
+ 45 +
+
+
    let solver = solver.load_model(model)?;
+
+
+
+ 71 +
+
+ +
+
+

+            
+
+
+ 72 +
+
+ 45 +
+
+
    println!("Running Minion...");
+
+
+
+ 73 +
+
+ 45 +
+
+

+            
+
+
+ 74 +
+
+ 45 +
+
+
    let all_solutions_ref = Arc::new(Mutex::<Vec<HashMap<Name, Constant>>>::new(vec![]));
+
+
+
+ 75 +
+
+ 45 +
+
+
    let all_solutions_ref_2 = all_solutions_ref.clone();
+
+
+
+ 76 +
+
+ 45 +
+
+
    #[allow(clippy::unwrap_used)]
+
+
+
+ 77 +
+
+ 45 +
+
+
    let solver = solver
+
+
+
+ 78 +
+
+ 175 +
+
+
        .solve(Box::new(move |sols| {
+
+
+
+ 79 +
+
+ 175 +
+
+
            let mut all_solutions = (*all_solutions_ref_2).lock().unwrap();
+
+
+
+ 80 +
+
+ 175 +
+
+
            (*all_solutions).push(sols);
+
+
+
+ 81 +
+
+ 175 +
+
+
            true
+
+
+
+ 82 +
+
+ 175 +
+
+
        }))
+
+
+
+ 83 +
+
+ 45 +
+
+
        .unwrap();
+
+
+
+ 84 +
+
+ 45 +
+
+

+            
+
+
+ 85 +
+
+ 45 +
+
+
    solver.save_stats_to_context();
+
+
+
+ 86 +
+
+ 45 +
+
+

+            
+
+
+ 87 +
+
+ 45 +
+
+
    #[allow(clippy::unwrap_used)]
+
+
+
+ 88 +
+
+ 45 +
+
+
    let sols = (*all_solutions_ref).lock().unwrap();
+
+
+
+ 89 +
+
+ 45 +
+
+

+            
+
+
+ 90 +
+
+ 45 +
+
+
    Ok((*sols).clone())
+
+
+
+ 91 +
+
+ 45 +
+
+
}
+
+
+
+ 92 +
+
+ +
+
+

+            
+
+
+ 93 +
+
+ 45 +
+
+
pub fn minion_solutions_to_json(solutions: &Vec<HashMap<Name, Constant>>) -> JsonValue {
+
+
+
+ 94 +
+
+ 45 +
+
+
    let mut json_solutions = Vec::new();
+
+
+
+ 95 +
+
+ 220 +
+
+
    for solution in solutions {
+
+
+
+ 96 +
+
+ 175 +
+
+
        let mut json_solution = Map::new();
+
+
+
+ 97 +
+
+ 650 +
+
+
        for (var_name, constant) in solution {
+
+
+
+ 98 +
+
+ 475 +
+
+
            let serialized_constant = match constant {
+
+
+
+ 99 +
+
+ 475 +
+
+
                Constant::Int(i) => JsonValue::Number((*i).into()),
+
+
+
+ 100 +
+
+ +
+
+
                Constant::Bool(b) => JsonValue::Bool(*b),
+
+
+
+ 101 +
+
+ +
+
+
            };
+
+
+
+ 102 +
+
+ 475 +
+
+
            json_solution.insert(var_name.to_string(), serialized_constant);
+
+
+
+ 103 +
+
+ +
+
+
        }
+
+
+
+ 104 +
+
+ 175 +
+
+
        json_solutions.push(JsonValue::Object(json_solution));
+
+
+
+ 105 +
+
+ +
+
+
    }
+
+
+
+ 106 +
+
+ 45 +
+
+
    let ans = JsonValue::Array(json_solutions);
+
+
+
+ 107 +
+
+ 45 +
+
+
    sort_json_object(&ans, true)
+
+
+
+ 108 +
+
+ 45 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/utils/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/utils/index.html new file mode 100644 index 0000000000..9fba7128b3 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/utils/index.html @@ -0,0 +1,146 @@ + + + + + Grcov report - conjure_oxide/src/utils + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
conjure.rs + + 80% + + + 80% + + 56 / 70 + 22.22%4 / 18
json.rs + + 80.77% + + + 80.77% + + 42 / 52 + 33.33%6 / 18
misc.rs + + 0% + + + 0% + + 0 / 7 + 0%0 / 3
testing.rs + + 59.35% + + + 59.35% + + 73 / 123 + 25%6 / 24
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/utils/json.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/utils/json.rs.html new file mode 100644 index 0000000000..8cc04f37cb --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/utils/json.rs.html @@ -0,0 +1,1305 @@ + + + + + Grcov report - json.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use serde_json::Value;
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
/// Compare two JSON values.
+
+
+
+ 4 +
+
+ +
+
+
/// If the values are String, Number, or Bool, they are compared directly.
+
+
+
+ 5 +
+
+ +
+
+
/// If the values are arrays, they are compared element-wise.
+
+
+
+ 6 +
+
+ +
+
+
/// Otherwise, they are compared as strings.
+
+
+
+ 7 +
+
+ 590 +
+
+
fn json_value_cmp(a: &Value, b: &Value) -> std::cmp::Ordering {
+
+
+
+ 8 +
+
+ 590 +
+
+
    match (a, b) {
+
+
+
+ 9 +
+
+ +
+
+
        (Value::Null, Value::Null) => std::cmp::Ordering::Equal,
+
+
+
+ 10 +
+
+ +
+
+
        (Value::Bool(a), Value::Bool(b)) => a.cmp(b),
+
+
+
+ 11 +
+
+ +
+
+
        (Value::String(a), Value::String(b)) => a.cmp(b),
+
+
+
+ 12 +
+
+ +
+
+
        (Value::Number(a), Value::Number(b)) => {
+
+
+
+ 13 +
+
+ +
+
+
            let af = a.as_f64().unwrap_or_default();
+
+
+
+ 14 +
+
+ +
+
+
            let bf = b.as_f64().unwrap_or_default();
+
+
+
+ 15 +
+
+ +
+
+
            af.total_cmp(&bf)
+
+
+
+ 16 +
+
+ +
+
+
        }
+
+
+
+ 17 +
+
+ 135 +
+
+
        (Value::Array(a), Value::Array(b)) => {
+
+
+
+ 18 +
+
+ 135 +
+
+
            for (a, b) in a.iter().zip(b.iter()) {
+
+
+
+ 19 +
+
+ 135 +
+
+
                let cmp = json_value_cmp(a, b);
+
+
+
+ 20 +
+
+ 135 +
+
+
                if cmp != std::cmp::Ordering::Equal {
+
+
+
+ 21 +
+
+ 135 +
+
+
                    return cmp;
+
+
+
+ 22 +
+
+ +
+
+
                }
+
+
+
+ 23 +
+
+ +
+
+
            }
+
+
+
+ 24 +
+
+ +
+
+
            std::cmp::Ordering::Equal
+
+
+
+ 25 +
+
+ +
+
+
        }
+
+
+
+ 26 +
+
+ 455 +
+
+
        _ => a.to_string().cmp(&b.to_string()),
+
+
+
+ 27 +
+
+ +
+
+
    }
+
+
+
+ 28 +
+
+ 590 +
+
+
}
+
+
+
+ 29 +
+
+ +
+
+

+            
+
+
+ 30 +
+
+ +
+
+
/// Sort the "variables" field by name.
+
+
+
+ 31 +
+
+ +
+
+
/// We have to do this separately because that field is not a JSON object, instead it's an array of tuples.
+
+
+
+ 32 +
+
+ 90 +
+
+
pub fn sort_json_variables(value: &Value) -> Value {
+
+
+
+ 33 +
+
+ 90 +
+
+
    match value {
+
+
+
+ 34 +
+
+ 90 +
+
+
        Value::Array(vars) => {
+
+
+
+ 35 +
+
+ 90 +
+
+
            let mut vars_sorted = vars.clone();
+
+
+
+ 36 +
+
+ 90 +
+
+
            vars_sorted.sort_by(json_value_cmp);
+
+
+
+ 37 +
+
+ 90 +
+
+
            Value::Array(vars_sorted)
+
+
+
+ 38 +
+
+ +
+
+
        }
+
+
+
+ 39 +
+
+ +
+
+
        _ => value.clone(),
+
+
+
+ 40 +
+
+ +
+
+
    }
+
+
+
+ 41 +
+
+ 90 +
+
+
}
+
+
+
+ 42 +
+
+ +
+
+

+            
+
+
+ 43 +
+
+ +
+
+
/// Recursively sorts the keys of all JSON objects within the provided JSON value.
+
+
+
+ 44 +
+
+ +
+
+
///
+
+
+
+ 45 +
+
+ +
+
+
/// serde_json will output JSON objects in an arbitrary key order.
+
+
+
+ 46 +
+
+ +
+
+
/// this is normally fine, except in our use case we wouldn't want to update the expected output again and again.
+
+
+
+ 47 +
+
+ +
+
+
/// so a consistent (sorted) ordering of the keys is desirable.
+
+
+
+ 48 +
+
+ 10230 +
+
+
pub fn sort_json_object(value: &Value, sort_arrays: bool) -> Value {
+
+
+
+ 49 +
+
+ 10230 +
+
+
    match value {
+
+
+
+ 50 +
+
+ 4600 +
+
+
        Value::Object(obj) => {
+
+
+
+ 51 +
+
+ 4600 +
+
+
            let mut ordered: Vec<(String, Value)> = obj
+
+
+
+ 52 +
+
+ 4600 +
+
+
                .iter()
+
+
+
+ 53 +
+
+ 5560 +
+
+
                .map(|(k, v)| {
+
+
+
+ 54 +
+
+ 5560 +
+
+
                    if k == "variables" {
+
+
+
+ 55 +
+
+ 90 +
+
+
                        (k.clone(), sort_json_variables(v))
+
+
+
+ 56 +
+
+ +
+
+
                    } else {
+
+
+
+ 57 +
+
+ 5470 +
+
+
                        (k.clone(), sort_json_object(v, sort_arrays))
+
+
+
+ 58 +
+
+ +
+
+
                    }
+
+
+
+ 59 +
+
+ 5560 +
+
+
                })
+
+
+
+ 60 +
+
+ 4600 +
+
+
                .collect();
+
+
+
+ 61 +
+
+ 4600 +
+
+

+            
+
+
+ 62 +
+
+ 4600 +
+
+
            ordered.sort_by(|a, b| a.0.cmp(&b.0));
+
+
+
+ 63 +
+
+ 4600 +
+
+
            Value::Object(ordered.into_iter().collect())
+
+
+
+ 64 +
+
+ +
+
+
        }
+
+
+
+ 65 +
+
+ 1875 +
+
+
        Value::Array(arr) => {
+
+
+
+ 66 +
+
+ 1875 +
+
+
            let mut arr: Vec<Value> = arr
+
+
+
+ 67 +
+
+ 1875 +
+
+
                .iter()
+
+
+
+ 68 +
+
+ 4535 +
+
+
                .map(|val| sort_json_object(val, sort_arrays))
+
+
+
+ 69 +
+
+ 1875 +
+
+
                .collect();
+
+
+
+ 70 +
+
+ 1875 +
+
+

+            
+
+
+ 71 +
+
+ 1875 +
+
+
            if sort_arrays {
+
+
+
+ 72 +
+
+ 90 +
+
+
                arr.sort_by(json_value_cmp);
+
+
+
+ 73 +
+
+ 1785 +
+
+
            }
+
+
+
+ 74 +
+
+ +
+
+

+            
+
+
+ 75 +
+
+ 1875 +
+
+
            Value::Array(arr)
+
+
+
+ 76 +
+
+ +
+
+
        }
+
+
+
+ 77 +
+
+ 3755 +
+
+
        _ => value.clone(),
+
+
+
+ 78 +
+
+ +
+
+
    }
+
+
+
+ 79 +
+
+ 10230 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/utils/misc.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/utils/misc.rs.html new file mode 100644 index 0000000000..1b63d611e6 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/utils/misc.rs.html @@ -0,0 +1,217 @@ + + + + + Grcov report - misc.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use std::collections::HashSet;
+
+
+
+ 2 +
+
+ +
+
+
use std::fmt::Debug;
+
+
+
+ 3 +
+
+ +
+
+
use std::hash::Hash;
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ +
+
+
pub fn to_set<T: Eq + Hash + Debug + Clone>(a: &Vec<T>) -> HashSet<T> {
+
+
+
+ 6 +
+
+ +
+
+
    let mut a_set: HashSet<T> = HashSet::new();
+
+
+
+ 7 +
+
+ +
+
+
    for el in a {
+
+
+
+ 8 +
+
+ +
+
+
        a_set.insert(el.clone());
+
+
+
+ 9 +
+
+ +
+
+
    }
+
+
+
+ 10 +
+
+ +
+
+
    a_set
+
+
+
+ 11 +
+
+ +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/utils/testing.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/utils/testing.rs.html new file mode 100644 index 0000000000..f92e0fc765 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/src/utils/testing.rs.html @@ -0,0 +1,3001 @@ + + + + + Grcov report - testing.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use std::collections::{HashMap, HashSet};
+
+
+
+ 2 +
+
+ +
+
+
use std::fmt::Debug;
+
+
+
+ 3 +
+
+ +
+
+
use std::fs::File;
+
+
+
+ 4 +
+
+ +
+
+
use std::hash::Hash;
+
+
+
+ 5 +
+
+ +
+
+
use std::io::Write;
+
+
+
+ 6 +
+
+ +
+
+
use std::sync::{Arc, RwLock};
+
+
+
+ 7 +
+
+ +
+
+

+            
+
+
+ 8 +
+
+ +
+
+
use conjure_core::context::Context;
+
+
+
+ 9 +
+
+ +
+
+
use serde_json::{Error as JsonError, Value as JsonValue};
+
+
+
+ 10 +
+
+ +
+
+

+            
+
+
+ 11 +
+
+ +
+
+
use conjure_core::error::Error;
+
+
+
+ 12 +
+
+ +
+
+

+            
+
+
+ 13 +
+
+ +
+
+
use crate::ast::Name::UserName;
+
+
+
+ 14 +
+
+ +
+
+
use crate::ast::{Constant, Name};
+
+
+
+ 15 +
+
+ +
+
+
use crate::utils::conjure::minion_solutions_to_json;
+
+
+
+ 16 +
+
+ +
+
+
use crate::utils::json::sort_json_object;
+
+
+
+ 17 +
+
+ +
+
+
use crate::utils::misc::to_set;
+
+
+
+ 18 +
+
+ +
+
+
use crate::Model as ConjureModel;
+
+
+
+ 19 +
+
+ +
+
+

+            
+
+
+ 20 +
+
+ +
+
+
pub fn assert_eq_any_order<T: Eq + Hash + Debug + Clone>(a: &Vec<Vec<T>>, b: &Vec<Vec<T>>) {
+
+
+
+ 21 +
+
+ +
+
+
    assert_eq!(a.len(), b.len());
+
+
+
+ 22 +
+
+ +
+
+

+            
+
+
+ 23 +
+
+ +
+
+
    let mut a_rows: Vec<HashSet<T>> = Vec::new();
+
+
+
+ 24 +
+
+ +
+
+
    for row in a {
+
+
+
+ 25 +
+
+ +
+
+
        let hash_row = to_set(row);
+
+
+
+ 26 +
+
+ +
+
+
        a_rows.push(hash_row);
+
+
+
+ 27 +
+
+ +
+
+
    }
+
+
+
+ 28 +
+
+ +
+
+

+            
+
+
+ 29 +
+
+ +
+
+
    let mut b_rows: Vec<HashSet<T>> = Vec::new();
+
+
+
+ 30 +
+
+ +
+
+
    for row in b {
+
+
+
+ 31 +
+
+ +
+
+
        let hash_row = to_set(row);
+
+
+
+ 32 +
+
+ +
+
+
        b_rows.push(hash_row);
+
+
+
+ 33 +
+
+ +
+
+
    }
+
+
+
+ 34 +
+
+ +
+
+

+            
+
+
+ 35 +
+
+ +
+
+
    println!("{:?},{:?}", a_rows, b_rows);
+
+
+
+ 36 +
+
+ +
+
+
    for row in a_rows {
+
+
+
+ 37 +
+
+ +
+
+
        assert!(b_rows.contains(&row));
+
+
+
+ 38 +
+
+ +
+
+
    }
+
+
+
+ 39 +
+
+ +
+
+
}
+
+
+
+ 40 +
+
+ +
+
+

+            
+
+
+ 41 +
+
+ 90 +
+
+
pub fn serialise_model(model: &ConjureModel) -> Result<String, JsonError> {
+
+
+
+ 42 +
+
+ +
+
+
    // A consistent sorting of the keys of json objects
+
+
+
+ 43 +
+
+ +
+
+
    // only required for the generated version
+
+
+
+ 44 +
+
+ +
+
+
    // since the expected version will already be sorted
+
+
+
+ 45 +
+
+ 90 +
+
+
    let generated_json = sort_json_object(&serde_json::to_value(model.clone())?, false);
+
+
+
+ 46 +
+
+ +
+
+

+            
+
+
+ 47 +
+
+ +
+
+
    // serialise to string
+
+
+
+ 48 +
+
+ 90 +
+
+
    let generated_json_str = serde_json::to_string_pretty(&generated_json)?;
+
+
+
+ 49 +
+
+ +
+
+

+            
+
+
+ 50 +
+
+ 90 +
+
+
    Ok(generated_json_str)
+
+
+
+ 51 +
+
+ 90 +
+
+
}
+
+
+
+ 52 +
+
+ +
+
+

+            
+
+
+ 53 +
+
+ 90 +
+
+
pub fn save_model_json(
+
+
+
+ 54 +
+
+ 90 +
+
+
    model: &ConjureModel,
+
+
+
+ 55 +
+
+ 90 +
+
+
    path: &str,
+
+
+
+ 56 +
+
+ 90 +
+
+
    test_name: &str,
+
+
+
+ 57 +
+
+ 90 +
+
+
    test_stage: &str,
+
+
+
+ 58 +
+
+ 90 +
+
+
    accept: bool,
+
+
+
+ 59 +
+
+ 90 +
+
+
) -> Result<(), std::io::Error> {
+
+
+
+ 60 +
+
+ 90 +
+
+
    let generated_json_str = serialise_model(model)?;
+
+
+
+ 61 +
+
+ +
+
+

+            
+
+
+ 62 +
+
+ 90 +
+
+
    File::create(format!(
+
+
+
+ 63 +
+
+ 90 +
+
+
        "{path}/{test_name}.generated-{test_stage}.serialised.json"
+
+
+
+ 64 +
+
+ 90 +
+
+
    ))?
+
+
+
+ 65 +
+
+ 90 +
+
+
    .write_all(generated_json_str.as_bytes())?;
+
+
+
+ 66 +
+
+ +
+
+

+            
+
+
+ 67 +
+
+ 90 +
+
+
    if accept {
+
+
+
+ 68 +
+
+ +
+
+
        std::fs::copy(
+
+
+
+ 69 +
+
+ +
+
+
            format!("{path}/{test_name}.generated-{test_stage}.serialised.json"),
+
+
+
+ 70 +
+
+ +
+
+
            format!("{path}/{test_name}.expected-{test_stage}.serialised.json"),
+
+
+
+ 71 +
+
+ +
+
+
        )?;
+
+
+
+ 72 +
+
+ 90 +
+
+
    }
+
+
+
+ 73 +
+
+ +
+
+

+            
+
+
+ 74 +
+
+ 90 +
+
+
    Ok(())
+
+
+
+ 75 +
+
+ 90 +
+
+
}
+
+
+
+ 76 +
+
+ +
+
+

+            
+
+
+ 77 +
+
+ 45 +
+
+
pub fn save_stats_json(
+
+
+
+ 78 +
+
+ 45 +
+
+
    context: Arc<RwLock<Context<'static>>>,
+
+
+
+ 79 +
+
+ 45 +
+
+
    path: &str,
+
+
+
+ 80 +
+
+ 45 +
+
+
    test_name: &str,
+
+
+
+ 81 +
+
+ 45 +
+
+
) -> Result<(), std::io::Error> {
+
+
+
+ 82 +
+
+ 45 +
+
+
    #[allow(clippy::unwrap_used)]
+
+
+
+ 83 +
+
+ 45 +
+
+
    let stats = context.read().unwrap().clone();
+
+
+
+ 84 +
+
+ 45 +
+
+
    let generated_json = sort_json_object(&serde_json::to_value(stats)?, false);
+
+
+
+ 85 +
+
+ +
+
+

+            
+
+
+ 86 +
+
+ +
+
+
    // serialise to string
+
+
+
+ 87 +
+
+ 45 +
+
+
    let generated_json_str = serde_json::to_string_pretty(&generated_json)?;
+
+
+
+ 88 +
+
+ +
+
+

+            
+
+
+ 89 +
+
+ 45 +
+
+
    File::create(format!("{path}/{test_name}-stats.json"))?
+
+
+
+ 90 +
+
+ 45 +
+
+
        .write_all(generated_json_str.as_bytes())?;
+
+
+
+ 91 +
+
+ +
+
+

+            
+
+
+ 92 +
+
+ 45 +
+
+
    Ok(())
+
+
+
+ 93 +
+
+ 45 +
+
+
}
+
+
+
+ 94 +
+
+ +
+
+

+            
+
+
+ 95 +
+
+ 90 +
+
+
pub fn read_model_json(
+
+
+
+ 96 +
+
+ 90 +
+
+
    path: &str,
+
+
+
+ 97 +
+
+ 90 +
+
+
    test_name: &str,
+
+
+
+ 98 +
+
+ 90 +
+
+
    prefix: &str,
+
+
+
+ 99 +
+
+ 90 +
+
+
    test_stage: &str,
+
+
+
+ 100 +
+
+ 90 +
+
+
) -> Result<ConjureModel, std::io::Error> {
+
+
+
+ 101 +
+
+ 90 +
+
+
    let expected_json_str = std::fs::read_to_string(format!(
+
+
+
+ 102 +
+
+ 90 +
+
+
        "{path}/{test_name}.{prefix}-{test_stage}.serialised.json"
+
+
+
+ 103 +
+
+ 90 +
+
+
    ))?;
+
+
+
+ 104 +
+
+ +
+
+

+            
+
+
+ 105 +
+
+ 90 +
+
+
    let expected_model: ConjureModel = serde_json::from_str(&expected_json_str)?;
+
+
+
+ 106 +
+
+ +
+
+

+            
+
+
+ 107 +
+
+ 90 +
+
+
    Ok(expected_model)
+
+
+
+ 108 +
+
+ 90 +
+
+
}
+
+
+
+ 109 +
+
+ +
+
+

+            
+
+
+ 110 +
+
+ +
+
+
pub fn minion_solutions_from_json(
+
+
+
+ 111 +
+
+ +
+
+
    serialized: &str,
+
+
+
+ 112 +
+
+ +
+
+
) -> Result<Vec<HashMap<Name, Constant>>, anyhow::Error> {
+
+
+
+ 113 +
+
+ +
+
+
    let json: JsonValue = serde_json::from_str(serialized)?;
+
+
+
+ 114 +
+
+ +
+
+

+            
+
+
+ 115 +
+
+ +
+
+
    let json_array = json
+
+
+
+ 116 +
+
+ +
+
+
        .as_array()
+
+
+
+ 117 +
+
+ +
+
+
        .ok_or(Error::Parse("Invalid JSON".to_owned()))?;
+
+
+
+ 118 +
+
+ +
+
+

+            
+
+
+ 119 +
+
+ +
+
+
    let mut solutions = Vec::new();
+
+
+
+ 120 +
+
+ +
+
+

+            
+
+
+ 121 +
+
+ +
+
+
    for solution in json_array {
+
+
+
+ 122 +
+
+ +
+
+
        let mut sol = HashMap::new();
+
+
+
+ 123 +
+
+ +
+
+
        let solution = solution
+
+
+
+ 124 +
+
+ +
+
+
            .as_object()
+
+
+
+ 125 +
+
+ +
+
+
            .ok_or(Error::Parse("Invalid JSON".to_owned()))?;
+
+
+
+ 126 +
+
+ +
+
+

+            
+
+
+ 127 +
+
+ +
+
+
        for (var_name, constant) in solution {
+
+
+
+ 128 +
+
+ +
+
+
            let constant = match constant {
+
+
+
+ 129 +
+
+ +
+
+
                JsonValue::Number(n) => {
+
+
+
+ 130 +
+
+ +
+
+
                    let n = n
+
+
+
+ 131 +
+
+ +
+
+
                        .as_i64()
+
+
+
+ 132 +
+
+ +
+
+
                        .ok_or(Error::Parse("Invalid integer".to_owned()))?;
+
+
+
+ 133 +
+
+ +
+
+
                    Constant::Int(n as i32)
+
+
+
+ 134 +
+
+ +
+
+
                }
+
+
+
+ 135 +
+
+ +
+
+
                JsonValue::Bool(b) => Constant::Bool(*b),
+
+
+
+ 136 +
+
+ +
+
+
                _ => return Err(Error::Parse("Invalid constant".to_owned()).into()),
+
+
+
+ 137 +
+
+ +
+
+
            };
+
+
+
+ 138 +
+
+ +
+
+

+            
+
+
+ 139 +
+
+ +
+
+
            sol.insert(UserName(var_name.into()), constant);
+
+
+
+ 140 +
+
+ +
+
+
        }
+
+
+
+ 141 +
+
+ +
+
+

+            
+
+
+ 142 +
+
+ +
+
+
        solutions.push(sol);
+
+
+
+ 143 +
+
+ +
+
+
    }
+
+
+
+ 144 +
+
+ +
+
+

+            
+
+
+ 145 +
+
+ +
+
+
    Ok(solutions)
+
+
+
+ 146 +
+
+ +
+
+
}
+
+
+
+ 147 +
+
+ +
+
+

+            
+
+
+ 148 +
+
+ 45 +
+
+
pub fn save_minion_solutions_json(
+
+
+
+ 149 +
+
+ 45 +
+
+
    solutions: &Vec<HashMap<Name, Constant>>,
+
+
+
+ 150 +
+
+ 45 +
+
+
    path: &str,
+
+
+
+ 151 +
+
+ 45 +
+
+
    test_name: &str,
+
+
+
+ 152 +
+
+ 45 +
+
+
    accept: bool,
+
+
+
+ 153 +
+
+ 45 +
+
+
) -> Result<JsonValue, std::io::Error> {
+
+
+
+ 154 +
+
+ 45 +
+
+
    let json_solutions = minion_solutions_to_json(solutions);
+
+
+
+ 155 +
+
+ +
+
+

+            
+
+
+ 156 +
+
+ 45 +
+
+
    let generated_json_str = serde_json::to_string_pretty(&json_solutions)?;
+
+
+
+ 157 +
+
+ +
+
+

+            
+
+
+ 158 +
+
+ 45 +
+
+
    File::create(format!(
+
+
+
+ 159 +
+
+ 45 +
+
+
        "{path}/{test_name}.generated-minion.solutions.json"
+
+
+
+ 160 +
+
+ 45 +
+
+
    ))?
+
+
+
+ 161 +
+
+ 45 +
+
+
    .write_all(generated_json_str.as_bytes())?;
+
+
+
+ 162 +
+
+ +
+
+

+            
+
+
+ 163 +
+
+ 45 +
+
+
    if accept {
+
+
+
+ 164 +
+
+ +
+
+
        std::fs::copy(
+
+
+
+ 165 +
+
+ +
+
+
            format!("{path}/{test_name}.generated-minion.solutions.json"),
+
+
+
+ 166 +
+
+ +
+
+
            format!("{path}/{test_name}.expected-minion.solutions.json"),
+
+
+
+ 167 +
+
+ +
+
+
        )?;
+
+
+
+ 168 +
+
+ 45 +
+
+
    }
+
+
+
+ 169 +
+
+ +
+
+

+            
+
+
+ 170 +
+
+ 45 +
+
+
    Ok(json_solutions)
+
+
+
+ 171 +
+
+ 45 +
+
+
}
+
+
+
+ 172 +
+
+ +
+
+

+            
+
+
+ 173 +
+
+ 45 +
+
+
pub fn read_minion_solutions_json(
+
+
+
+ 174 +
+
+ 45 +
+
+
    path: &str,
+
+
+
+ 175 +
+
+ 45 +
+
+
    test_name: &str,
+
+
+
+ 176 +
+
+ 45 +
+
+
    prefix: &str,
+
+
+
+ 177 +
+
+ 45 +
+
+
) -> Result<JsonValue, anyhow::Error> {
+
+
+
+ 178 +
+
+ 45 +
+
+
    let expected_json_str =
+
+
+
+ 179 +
+
+ 45 +
+
+
        std::fs::read_to_string(format!("{path}/{test_name}.{prefix}-minion.solutions.json"))?;
+
+
+
+ 180 +
+
+ +
+
+

+            
+
+
+ 181 +
+
+ 45 +
+
+
    let expected_solutions: JsonValue =
+
+
+
+ 182 +
+
+ 45 +
+
+
        sort_json_object(&serde_json::from_str(&expected_json_str)?, true);
+
+
+
+ 183 +
+
+ +
+
+

+            
+
+
+ 184 +
+
+ 45 +
+
+
    Ok(expected_solutions)
+
+
+
+ 185 +
+
+ 45 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/tests/generated_tests.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/tests/generated_tests.rs.html new file mode 100644 index 0000000000..d0a194af1a --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/tests/generated_tests.rs.html @@ -0,0 +1,1561 @@ + + + + + Grcov report - generated_tests.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use std::env;
+
+
+
+ 2 +
+
+ +
+
+
use std::error::Error;
+
+
+
+ 3 +
+
+ +
+
+
use std::path::Path;
+
+
+
+ 4 +
+
+ +
+
+
use std::sync::Arc;
+
+
+
+ 5 +
+
+ +
+
+
use std::sync::RwLock;
+
+
+
+ 6 +
+
+ +
+
+

+            
+
+
+ 7 +
+
+ +
+
+
use conjure_core::context::Context;
+
+
+
+ 8 +
+
+ +
+
+
use conjure_oxide::rule_engine::resolve_rule_sets;
+
+
+
+ 9 +
+
+ +
+
+
use conjure_oxide::rule_engine::rewrite_model;
+
+
+
+ 10 +
+
+ +
+
+
use conjure_oxide::utils::conjure::{get_minion_solutions, parse_essence_file};
+
+
+
+ 11 +
+
+ +
+
+
use conjure_oxide::utils::testing::save_stats_json;
+
+
+
+ 12 +
+
+ +
+
+
use conjure_oxide::utils::testing::{
+
+
+
+ 13 +
+
+ +
+
+
    read_minion_solutions_json, read_model_json, save_minion_solutions_json, save_model_json,
+
+
+
+ 14 +
+
+ +
+
+
};
+
+
+
+ 15 +
+
+ +
+
+
use conjure_oxide::SolverFamily;
+
+
+
+ 16 +
+
+ +
+
+

+            
+
+
+ 17 +
+
+ +
+
+
fn main() {
+
+
+
+ 18 +
+
+ +
+
+
    let file_path = Path::new("/path/to/your/file.txt");
+
+
+
+ 19 +
+
+ +
+
+
    let base_name = file_path.file_stem().and_then(|stem| stem.to_str());
+
+
+
+ 20 +
+
+ +
+
+

+            
+
+
+ 21 +
+
+ +
+
+
    match base_name {
+
+
+
+ 22 +
+
+ +
+
+
        Some(name) => println!("Base name: {}", name),
+
+
+
+ 23 +
+
+ +
+
+
        None => println!("Could not extract the base name"),
+
+
+
+ 24 +
+
+ +
+
+
    }
+
+
+
+ 25 +
+
+ +
+
+
}
+
+
+
+ 26 +
+
+ +
+
+

+            
+
+
+ 27 +
+
+ +
+
+
#[allow(clippy::unwrap_used)]
+
+
+
+ 28 +
+
+ 9 +
+
+
fn integration_test(path: &str, essence_base: &str) -> Result<(), Box<dyn Error>> {
+
+
+
+ 29 +
+
+ 9 +
+
+
    let context: Arc<RwLock<Context<'static>>> = Default::default();
+
+
+
+ 30 +
+
+ 9 +
+
+
    let accept = env::var("ACCEPT").unwrap_or("false".to_string()) == "true";
+
+
+
+ 31 +
+
+ 9 +
+
+
    let verbose = env::var("VERBOSE").unwrap_or("false".to_string()) == "true";
+
+
+
+ 32 +
+
+ 9 +
+
+

+            
+
+
+ 33 +
+
+ 9 +
+
+
    if verbose {
+
+
+
+ 34 +
+
+ +
+
+
        println!(
+
+
+
+ 35 +
+
+ +
+
+
            "Running integration test for {}/{}, ACCEPT={}",
+
+
+
+ 36 +
+
+ +
+
+
            path, essence_base, accept
+
+
+
+ 37 +
+
+ +
+
+
        );
+
+
+
+ 38 +
+
+ 9 +
+
+
    }
+
+
+
+ 39 +
+
+ +
+
+

+            
+
+
+ 40 +
+
+ +
+
+
    // Stage 1: Read the essence file and check that the model is parsed correctly
+
+
+
+ 41 +
+
+ 9 +
+
+
    let model = parse_essence_file(path, essence_base, context.clone())?;
+
+
+
+ 42 +
+
+ 9 +
+
+
    if verbose {
+
+
+
+ 43 +
+
+ +
+
+
        println!("Parsed model: {:#?}", model)
+
+
+
+ 44 +
+
+ 9 +
+
+
    }
+
+
+
+ 45 +
+
+ +
+
+

+            
+
+
+ 46 +
+
+ 9 +
+
+
    context.as_ref().write().unwrap().file_name = Some(format!("{path}/{essence_base}.essence"));
+
+
+
+ 47 +
+
+ 9 +
+
+

+            
+
+
+ 48 +
+
+ 9 +
+
+
    save_model_json(&model, path, essence_base, "parse", accept)?;
+
+
+
+ 49 +
+
+ 9 +
+
+
    let expected_model = read_model_json(path, essence_base, "expected", "parse")?;
+
+
+
+ 50 +
+
+ 9 +
+
+
    if verbose {
+
+
+
+ 51 +
+
+ +
+
+
        println!("Expected model: {:#?}", expected_model)
+
+
+
+ 52 +
+
+ 9 +
+
+
    }
+
+
+
+ 53 +
+
+ +
+
+

+            
+
+
+ 54 +
+
+ 9 +
+
+
    assert_eq!(model, expected_model);
+
+
+
+ 55 +
+
+ +
+
+

+            
+
+
+ 56 +
+
+ +
+
+
    // Stage 2: Rewrite the model using the rule engine and check that the result is as expected
+
+
+
+ 57 +
+
+ 9 +
+
+
    let rule_sets = resolve_rule_sets(SolverFamily::Minion, &vec!["Constant"])?;
+
+
+
+ 58 +
+
+ 9 +
+
+
    let model = rewrite_model(&model, &rule_sets)?;
+
+
+
+ 59 +
+
+ 9 +
+
+
    if verbose {
+
+
+
+ 60 +
+
+ +
+
+
        println!("Rewritten model: {:#?}", model)
+
+
+
+ 61 +
+
+ 9 +
+
+
    }
+
+
+
+ 62 +
+
+ +
+
+

+            
+
+
+ 63 +
+
+ 9 +
+
+
    save_model_json(&model, path, essence_base, "rewrite", accept)?;
+
+
+
+ 64 +
+
+ 9 +
+
+
    let expected_model = read_model_json(path, essence_base, "expected", "rewrite")?;
+
+
+
+ 65 +
+
+ 9 +
+
+
    if verbose {
+
+
+
+ 66 +
+
+ +
+
+
        println!("Expected model: {:#?}", expected_model)
+
+
+
+ 67 +
+
+ 9 +
+
+
    }
+
+
+
+ 68 +
+
+ +
+
+

+            
+
+
+ 69 +
+
+ 9 +
+
+
    assert_eq!(model, expected_model);
+
+
+
+ 70 +
+
+ +
+
+

+            
+
+
+ 71 +
+
+ +
+
+
    // Stage 3: Run the model through the Minion solver and check that the solutions are as expected
+
+
+
+ 72 +
+
+ 9 +
+
+
    let solutions = get_minion_solutions(model)?;
+
+
+
+ 73 +
+
+ 9 +
+
+
    let solutions_json = save_minion_solutions_json(&solutions, path, essence_base, accept)?;
+
+
+
+ 74 +
+
+ 9 +
+
+
    if verbose {
+
+
+
+ 75 +
+
+ +
+
+
        println!("Minion solutions: {:#?}", solutions_json)
+
+
+
+ 76 +
+
+ 9 +
+
+
    }
+
+
+
+ 77 +
+
+ +
+
+

+            
+
+
+ 78 +
+
+ 9 +
+
+
    let expected_solutions_json = read_minion_solutions_json(path, essence_base, "expected")?;
+
+
+
+ 79 +
+
+ 9 +
+
+
    if verbose {
+
+
+
+ 80 +
+
+ +
+
+
        println!("Expected solutions: {:#?}", expected_solutions_json)
+
+
+
+ 81 +
+
+ 9 +
+
+
    }
+
+
+
+ 82 +
+
+ +
+
+

+            
+
+
+ 83 +
+
+ 9 +
+
+
    assert_eq!(solutions_json, expected_solutions_json);
+
+
+
+ 84 +
+
+ +
+
+

+            
+
+
+ 85 +
+
+ 9 +
+
+
    save_stats_json(context, path, essence_base)?;
+
+
+
+ 86 +
+
+ +
+
+

+            
+
+
+ 87 +
+
+ 9 +
+
+
    Ok(())
+
+
+
+ 88 +
+
+ 9 +
+
+
}
+
+
+
+ 89 +
+
+ +
+
+

+            
+
+
+ 90 +
+
+ +
+
+
#[test]
+
+
+
+ 91 +
+
+ 1 +
+
+
fn assert_conjure_present() {
+
+
+
+ 92 +
+
+ 1 +
+
+
    conjure_oxide::find_conjure::conjure_executable().unwrap();
+
+
+
+ 93 +
+
+ 1 +
+
+
}
+
+
+
+ 94 +
+
+ +
+
+

+            
+
+
+ 95 +
+
+ +
+
+
include!(concat!(env!("OUT_DIR"), "/gen_tests.rs"));
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/tests/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/tests/index.html new file mode 100644 index 0000000000..6fc1a89d40 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/tests/index.html @@ -0,0 +1,122 @@ + + + + + Grcov report - conjure_oxide/tests + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
generated_tests.rs + + 68.97% + + + 68.97% + + 40 / 58 + 50%2 / 4
model_tests.rs + + 100% + + + 100% + + 20 / 20 + 100%1 / 1
rewrite_tests.rs + + 96.69% + + + 96.69% + + 906 / 937 + 100%42 / 42
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/tests/model_tests.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/tests/model_tests.rs.html new file mode 100644 index 0000000000..d3a6e4d630 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/tests/model_tests.rs.html @@ -0,0 +1,537 @@ + + + + + Grcov report - model_tests.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
// Tests for various functionalities of the Model
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
use std::collections::HashMap;
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ +
+
+
use conjure_core::context::Context;
+
+
+
+ 6 +
+
+ +
+
+
use conjure_core::metadata::Metadata;
+
+
+
+ 7 +
+
+ +
+
+
use conjure_core::model::Model;
+
+
+
+ 8 +
+
+ +
+
+
use conjure_oxide::ast::*;
+
+
+
+ 9 +
+
+ +
+
+

+            
+
+
+ 10 +
+
+ +
+
+
#[test]
+
+
+
+ 11 +
+
+ 1 +
+
+
fn modify_domain() {
+
+
+
+ 12 +
+
+ 1 +
+
+
    let a = Name::UserName(String::from("a"));
+
+
+
+ 13 +
+
+ 1 +
+
+

+            
+
+
+ 14 +
+
+ 1 +
+
+
    let d1 = Domain::IntDomain(vec![Range::Bounded(1, 3)]);
+
+
+
+ 15 +
+
+ 1 +
+
+
    let d2 = Domain::IntDomain(vec![Range::Bounded(1, 2)]);
+
+
+
+ 16 +
+
+ 1 +
+
+

+            
+
+
+ 17 +
+
+ 1 +
+
+
    let mut variables = HashMap::new();
+
+
+
+ 18 +
+
+ 1 +
+
+
    variables.insert(a.clone(), DecisionVariable { domain: d1.clone() });
+
+
+
+ 19 +
+
+ 1 +
+
+

+            
+
+
+ 20 +
+
+ 1 +
+
+
    let mut m = Model::new(
+
+
+
+ 21 +
+
+ 1 +
+
+
        variables,
+
+
+
+ 22 +
+
+ 1 +
+
+
        Expression::And(Metadata::new(), Vec::new()),
+
+
+
+ 23 +
+
+ 1 +
+
+
        Default::default(),
+
+
+
+ 24 +
+
+ 1 +
+
+
    );
+
+
+
+ 25 +
+
+ 1 +
+
+

+            
+
+
+ 26 +
+
+ 1 +
+
+
    assert_eq!(m.variables.get(&a).unwrap().domain, d1);
+
+
+
+ 27 +
+
+ +
+
+

+            
+
+
+ 28 +
+
+ 1 +
+
+
    m.update_domain(&a, d2.clone());
+
+
+
+ 29 +
+
+ 1 +
+
+

+            
+
+
+ 30 +
+
+ 1 +
+
+
    assert_eq!(m.variables.get(&a).unwrap().domain, d2);
+
+
+
+ 31 +
+
+ 1 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/tests/rewrite_tests.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/tests/rewrite_tests.rs.html new file mode 100644 index 0000000000..cfec3ae651 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/conjure_oxide/tests/rewrite_tests.rs.html @@ -0,0 +1,18233 @@ + + + + + Grcov report - rewrite_tests.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use core::panic;
+
+
+
+ 2 +
+
+ +
+
+
use std::collections::HashMap;
+
+
+
+ 3 +
+
+ +
+
+
use std::process::exit;
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ +
+
+
use conjure_core::context::Context;
+
+
+
+ 6 +
+
+ +
+
+
use conjure_core::rules::eval_constant;
+
+
+
+ 7 +
+
+ +
+
+
use conjure_core::solver::SolverFamily;
+
+
+
+ 8 +
+
+ +
+
+
use conjure_oxide::{
+
+
+
+ 9 +
+
+ +
+
+
    ast::*,
+
+
+
+ 10 +
+
+ +
+
+
    get_rule_by_name, get_rules,
+
+
+
+ 11 +
+
+ +
+
+
    rule_engine::{resolve_rule_sets, rewrite_model},
+
+
+
+ 12 +
+
+ +
+
+
    solver::{adaptors, Solver, SolverAdaptor as _},
+
+
+
+ 13 +
+
+ +
+
+
    Metadata, Model, Rule,
+
+
+
+ 14 +
+
+ +
+
+
};
+
+
+
+ 15 +
+
+ +
+
+
use uniplate::uniplate::Uniplate;
+
+
+
+ 16 +
+
+ +
+
+

+            
+
+
+ 17 +
+
+ +
+
+
#[test]
+
+
+
+ 18 +
+
+ 1 +
+
+
fn rules_present() {
+
+
+
+ 19 +
+
+ 1 +
+
+
    let rules = get_rules();
+
+
+
+ 20 +
+
+ 1 +
+
+
    assert!(!rules.is_empty());
+
+
+
+ 21 +
+
+ 1 +
+
+
}
+
+
+
+ 22 +
+
+ +
+
+

+            
+
+
+ 23 +
+
+ +
+
+
#[test]
+
+
+
+ 24 +
+
+ 1 +
+
+
fn sum_of_constants() {
+
+
+
+ 25 +
+
+ 1 +
+
+
    let valid_sum_expression = Expression::Sum(
+
+
+
+ 26 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 27 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 28 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Int(1)),
+
+
+
+ 29 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Int(2)),
+
+
+
+ 30 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Int(3)),
+
+
+
+ 31 +
+
+ 1 +
+
+
        ],
+
+
+
+ 32 +
+
+ 1 +
+
+
    );
+
+
+
+ 33 +
+
+ 1 +
+
+

+            
+
+
+ 34 +
+
+ 1 +
+
+
    let invalid_sum_expression = Expression::Sum(
+
+
+
+ 35 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 36 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 37 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Int(1)),
+
+
+
+ 38 +
+
+ 1 +
+
+
            Expression::Reference(Metadata::new(), Name::UserName(String::from("a"))),
+
+
+
+ 39 +
+
+ 1 +
+
+
        ],
+
+
+
+ 40 +
+
+ 1 +
+
+
    );
+
+
+
+ 41 +
+
+ 1 +
+
+

+            
+
+
+ 42 +
+
+ 1 +
+
+
    match evaluate_sum_of_constants(&valid_sum_expression) {
+
+
+
+ 43 +
+
+ 1 +
+
+
        Some(result) => assert_eq!(result, 6),
+
+
+
+ 44 +
+
+ +
+
+
        None => panic!(),
+
+
+
+ 45 +
+
+ +
+
+
    }
+
+
+
+ 46 +
+
+ +
+
+

+            
+
+
+ 47 +
+
+ 1 +
+
+
    if evaluate_sum_of_constants(&invalid_sum_expression).is_some() {
+
+
+
+ 48 +
+
+ +
+
+
        panic!()
+
+
+
+ 49 +
+
+ 1 +
+
+
    }
+
+
+
+ 50 +
+
+ 1 +
+
+
}
+
+
+
+ 51 +
+
+ +
+
+

+            
+
+
+ 52 +
+
+ 4 +
+
+
fn evaluate_sum_of_constants(expr: &Expression) -> Option<i32> {
+
+
+
+ 53 +
+
+ 4 +
+
+
    match expr {
+
+
+
+ 54 +
+
+ 4 +
+
+
        Expression::Sum(_metadata, expressions) => {
+
+
+
+ 55 +
+
+ 4 +
+
+
            let mut sum = 0;
+
+
+
+ 56 +
+
+ 12 +
+
+
            for e in expressions {
+
+
+
+ 57 +
+
+ 8 +
+
+
                match e {
+
+
+
+ 58 +
+
+ 8 +
+
+
                    Expression::Constant(_, Constant::Int(value)) => {
+
+
+
+ 59 +
+
+ 8 +
+
+
                        sum += value;
+
+
+
+ 60 +
+
+ 8 +
+
+
                    }
+
+
+
+ 61 +
+
+ 2 +
+
+
                    _ => return None,
+
+
+
+ 62 +
+
+ +
+
+
                }
+
+
+
+ 63 +
+
+ +
+
+
            }
+
+
+
+ 64 +
+
+ 2 +
+
+
            Some(sum)
+
+
+
+ 65 +
+
+ +
+
+
        }
+
+
+
+ 66 +
+
+ +
+
+
        _ => None,
+
+
+
+ 67 +
+
+ +
+
+
    }
+
+
+
+ 68 +
+
+ 4 +
+
+
}
+
+
+
+ 69 +
+
+ +
+
+

+            
+
+
+ 70 +
+
+ +
+
+
#[test]
+
+
+
+ 71 +
+
+ 1 +
+
+
fn recursive_sum_of_constants() {
+
+
+
+ 72 +
+
+ 1 +
+
+
    let complex_expression = Expression::Eq(
+
+
+
+ 73 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 74 +
+
+ 1 +
+
+
        Box::new(Expression::Sum(
+
+
+
+ 75 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 76 +
+
+ 1 +
+
+
            vec![
+
+
+
+ 77 +
+
+ 1 +
+
+
                Expression::Constant(Metadata::new(), Constant::Int(1)),
+
+
+
+ 78 +
+
+ 1 +
+
+
                Expression::Constant(Metadata::new(), Constant::Int(2)),
+
+
+
+ 79 +
+
+ 1 +
+
+
                Expression::Sum(
+
+
+
+ 80 +
+
+ 1 +
+
+
                    Metadata::new(),
+
+
+
+ 81 +
+
+ 1 +
+
+
                    vec![
+
+
+
+ 82 +
+
+ 1 +
+
+
                        Expression::Constant(Metadata::new(), Constant::Int(1)),
+
+
+
+ 83 +
+
+ 1 +
+
+
                        Expression::Constant(Metadata::new(), Constant::Int(2)),
+
+
+
+ 84 +
+
+ 1 +
+
+
                    ],
+
+
+
+ 85 +
+
+ 1 +
+
+
                ),
+
+
+
+ 86 +
+
+ 1 +
+
+
                Expression::Reference(Metadata::new(), Name::UserName(String::from("a"))),
+
+
+
+ 87 +
+
+ 1 +
+
+
            ],
+
+
+
+ 88 +
+
+ 1 +
+
+
        )),
+
+
+
+ 89 +
+
+ 1 +
+
+
        Box::new(Expression::Constant(Metadata::new(), Constant::Int(3))),
+
+
+
+ 90 +
+
+ 1 +
+
+
    );
+
+
+
+ 91 +
+
+ 1 +
+
+
    let correct_simplified_expression = Expression::Eq(
+
+
+
+ 92 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 93 +
+
+ 1 +
+
+
        Box::new(Expression::Sum(
+
+
+
+ 94 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 95 +
+
+ 1 +
+
+
            vec![
+
+
+
+ 96 +
+
+ 1 +
+
+
                Expression::Constant(Metadata::new(), Constant::Int(1)),
+
+
+
+ 97 +
+
+ 1 +
+
+
                Expression::Constant(Metadata::new(), Constant::Int(2)),
+
+
+
+ 98 +
+
+ 1 +
+
+
                Expression::Constant(Metadata::new(), Constant::Int(3)),
+
+
+
+ 99 +
+
+ 1 +
+
+
                Expression::Reference(Metadata::new(), Name::UserName(String::from("a"))),
+
+
+
+ 100 +
+
+ 1 +
+
+
            ],
+
+
+
+ 101 +
+
+ 1 +
+
+
        )),
+
+
+
+ 102 +
+
+ 1 +
+
+
        Box::new(Expression::Constant(Metadata::new(), Constant::Int(3))),
+
+
+
+ 103 +
+
+ 1 +
+
+
    );
+
+
+
+ 104 +
+
+ 1 +
+
+

+            
+
+
+ 105 +
+
+ 1 +
+
+
    let simplified_expression = simplify_expression(complex_expression.clone());
+
+
+
+ 106 +
+
+ 1 +
+
+
    assert_eq!(simplified_expression, correct_simplified_expression);
+
+
+
+ 107 +
+
+ 1 +
+
+
}
+
+
+
+ 108 +
+
+ +
+
+

+            
+
+
+ 109 +
+
+ 7 +
+
+
fn simplify_expression(expr: Expression) -> Expression {
+
+
+
+ 110 +
+
+ 7 +
+
+
    match expr {
+
+
+
+ 111 +
+
+ 2 +
+
+
        Expression::Sum(_metadata, expressions) => {
+
+
+
+ 112 +
+
+ 1 +
+
+
            if let Some(result) =
+
+
+
+ 113 +
+
+ 2 +
+
+
                evaluate_sum_of_constants(&Expression::Sum(Metadata::new(), expressions.clone()))
+
+
+
+ 114 +
+
+ +
+
+
            {
+
+
+
+ 115 +
+
+ 1 +
+
+
                Expression::Constant(Metadata::new(), Constant::Int(result))
+
+
+
+ 116 +
+
+ +
+
+
            } else {
+
+
+
+ 117 +
+
+ 1 +
+
+
                Expression::Sum(
+
+
+
+ 118 +
+
+ 1 +
+
+
                    Metadata::new(),
+
+
+
+ 119 +
+
+ 1 +
+
+
                    expressions.into_iter().map(simplify_expression).collect(),
+
+
+
+ 120 +
+
+ 1 +
+
+
                )
+
+
+
+ 121 +
+
+ +
+
+
            }
+
+
+
+ 122 +
+
+ +
+
+
        }
+
+
+
+ 123 +
+
+ 1 +
+
+
        Expression::Eq(_metadata, left, right) => Expression::Eq(
+
+
+
+ 124 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 125 +
+
+ 1 +
+
+
            Box::new(simplify_expression(*left)),
+
+
+
+ 126 +
+
+ 1 +
+
+
            Box::new(simplify_expression(*right)),
+
+
+
+ 127 +
+
+ 1 +
+
+
        ),
+
+
+
+ 128 +
+
+ +
+
+
        Expression::Geq(_metadata, left, right) => Expression::Geq(
+
+
+
+ 129 +
+
+ +
+
+
            Metadata::new(),
+
+
+
+ 130 +
+
+ +
+
+
            Box::new(simplify_expression(*left)),
+
+
+
+ 131 +
+
+ +
+
+
            Box::new(simplify_expression(*right)),
+
+
+
+ 132 +
+
+ +
+
+
        ),
+
+
+
+ 133 +
+
+ 4 +
+
+
        _ => expr,
+
+
+
+ 134 +
+
+ +
+
+
    }
+
+
+
+ 135 +
+
+ 7 +
+
+
}
+
+
+
+ 136 +
+
+ +
+
+

+            
+
+
+ 137 +
+
+ +
+
+
#[test]
+
+
+
+ 138 +
+
+ 1 +
+
+
fn rule_sum_constants() {
+
+
+
+ 139 +
+
+ 1 +
+
+
    let sum_constants = get_rule_by_name("sum_constants").unwrap();
+
+
+
+ 140 +
+
+ 1 +
+
+
    let unwrap_sum = get_rule_by_name("unwrap_sum").unwrap();
+
+
+
+ 141 +
+
+ 1 +
+
+

+            
+
+
+ 142 +
+
+ 1 +
+
+
    let mut expr = Expression::Sum(
+
+
+
+ 143 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 144 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 145 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Int(1)),
+
+
+
+ 146 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Int(2)),
+
+
+
+ 147 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Int(3)),
+
+
+
+ 148 +
+
+ 1 +
+
+
        ],
+
+
+
+ 149 +
+
+ 1 +
+
+
    );
+
+
+
+ 150 +
+
+ 1 +
+
+

+            
+
+
+ 151 +
+
+ 1 +
+
+
    expr = sum_constants
+
+
+
+ 152 +
+
+ 1 +
+
+
        .apply(&expr, &Model::new_empty(Default::default()))
+
+
+
+ 153 +
+
+ 1 +
+
+
        .unwrap()
+
+
+
+ 154 +
+
+ 1 +
+
+
        .new_expression;
+
+
+
+ 155 +
+
+ 1 +
+
+
    expr = unwrap_sum
+
+
+
+ 156 +
+
+ 1 +
+
+
        .apply(&expr, &Model::new_empty(Default::default()))
+
+
+
+ 157 +
+
+ 1 +
+
+
        .unwrap()
+
+
+
+ 158 +
+
+ 1 +
+
+
        .new_expression;
+
+
+
+ 159 +
+
+ 1 +
+
+

+            
+
+
+ 160 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 161 +
+
+ 1 +
+
+
        expr,
+
+
+
+ 162 +
+
+ 1 +
+
+
        Expression::Constant(Metadata::new(), Constant::Int(6))
+
+
+
+ 163 +
+
+ 1 +
+
+
    );
+
+
+
+ 164 +
+
+ 1 +
+
+
}
+
+
+
+ 165 +
+
+ +
+
+

+            
+
+
+ 166 +
+
+ +
+
+
#[test]
+
+
+
+ 167 +
+
+ 1 +
+
+
fn rule_sum_mixed() {
+
+
+
+ 168 +
+
+ 1 +
+
+
    let sum_constants = get_rule_by_name("sum_constants").unwrap();
+
+
+
+ 169 +
+
+ 1 +
+
+

+            
+
+
+ 170 +
+
+ 1 +
+
+
    let mut expr = Expression::Sum(
+
+
+
+ 171 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 172 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 173 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Int(1)),
+
+
+
+ 174 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Int(2)),
+
+
+
+ 175 +
+
+ 1 +
+
+
            Expression::Reference(Metadata::new(), Name::UserName(String::from("a"))),
+
+
+
+ 176 +
+
+ 1 +
+
+
        ],
+
+
+
+ 177 +
+
+ 1 +
+
+
    );
+
+
+
+ 178 +
+
+ 1 +
+
+

+            
+
+
+ 179 +
+
+ 1 +
+
+
    expr = sum_constants
+
+
+
+ 180 +
+
+ 1 +
+
+
        .apply(&expr, &Model::new_empty(Default::default()))
+
+
+
+ 181 +
+
+ 1 +
+
+
        .unwrap()
+
+
+
+ 182 +
+
+ 1 +
+
+
        .new_expression;
+
+
+
+ 183 +
+
+ 1 +
+
+

+            
+
+
+ 184 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 185 +
+
+ 1 +
+
+
        expr,
+
+
+
+ 186 +
+
+ 1 +
+
+
        Expression::Sum(
+
+
+
+ 187 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 188 +
+
+ 1 +
+
+
            vec![
+
+
+
+ 189 +
+
+ 1 +
+
+
                Expression::Reference(Metadata::new(), Name::UserName(String::from("a"))),
+
+
+
+ 190 +
+
+ 1 +
+
+
                Expression::Constant(Metadata::new(), Constant::Int(3)),
+
+
+
+ 191 +
+
+ 1 +
+
+
            ]
+
+
+
+ 192 +
+
+ 1 +
+
+
        )
+
+
+
+ 193 +
+
+ 1 +
+
+
    );
+
+
+
+ 194 +
+
+ 1 +
+
+
}
+
+
+
+ 195 +
+
+ +
+
+

+            
+
+
+ 196 +
+
+ +
+
+
#[test]
+
+
+
+ 197 +
+
+ 1 +
+
+
fn rule_sum_geq() {
+
+
+
+ 198 +
+
+ 1 +
+
+
    let flatten_sum_geq = get_rule_by_name("flatten_sum_geq").unwrap();
+
+
+
+ 199 +
+
+ 1 +
+
+

+            
+
+
+ 200 +
+
+ 1 +
+
+
    let mut expr = Expression::Geq(
+
+
+
+ 201 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 202 +
+
+ 1 +
+
+
        Box::new(Expression::Sum(
+
+
+
+ 203 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 204 +
+
+ 1 +
+
+
            vec![
+
+
+
+ 205 +
+
+ 1 +
+
+
                Expression::Constant(Metadata::new(), Constant::Int(1)),
+
+
+
+ 206 +
+
+ 1 +
+
+
                Expression::Constant(Metadata::new(), Constant::Int(2)),
+
+
+
+ 207 +
+
+ 1 +
+
+
            ],
+
+
+
+ 208 +
+
+ 1 +
+
+
        )),
+
+
+
+ 209 +
+
+ 1 +
+
+
        Box::new(Expression::Constant(Metadata::new(), Constant::Int(3))),
+
+
+
+ 210 +
+
+ 1 +
+
+
    );
+
+
+
+ 211 +
+
+ 1 +
+
+

+            
+
+
+ 212 +
+
+ 1 +
+
+
    expr = flatten_sum_geq
+
+
+
+ 213 +
+
+ 1 +
+
+
        .apply(&expr, &Model::new_empty(Default::default()))
+
+
+
+ 214 +
+
+ 1 +
+
+
        .unwrap()
+
+
+
+ 215 +
+
+ 1 +
+
+
        .new_expression;
+
+
+
+ 216 +
+
+ 1 +
+
+

+            
+
+
+ 217 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 218 +
+
+ 1 +
+
+
        expr,
+
+
+
+ 219 +
+
+ 1 +
+
+
        Expression::SumGeq(
+
+
+
+ 220 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 221 +
+
+ 1 +
+
+
            vec![
+
+
+
+ 222 +
+
+ 1 +
+
+
                Expression::Constant(Metadata::new(), Constant::Int(1)),
+
+
+
+ 223 +
+
+ 1 +
+
+
                Expression::Constant(Metadata::new(), Constant::Int(2)),
+
+
+
+ 224 +
+
+ 1 +
+
+
            ],
+
+
+
+ 225 +
+
+ 1 +
+
+
            Box::new(Expression::Constant(Metadata::new(), Constant::Int(3)))
+
+
+
+ 226 +
+
+ 1 +
+
+
        )
+
+
+
+ 227 +
+
+ 1 +
+
+
    );
+
+
+
+ 228 +
+
+ 1 +
+
+
}
+
+
+
+ 229 +
+
+ +
+
+

+            
+
+
+ 230 +
+
+ +
+
+
///
+
+
+
+ 231 +
+
+ +
+
+
/// Reduce and solve:
+
+
+
+ 232 +
+
+ +
+
+
/// ```text
+
+
+
+ 233 +
+
+ +
+
+
/// find a,b,c : int(1..3)
+
+
+
+ 234 +
+
+ +
+
+
/// such that a + b + c <= 2 + 3 - 1
+
+
+
+ 235 +
+
+ +
+
+
/// such that a < b
+
+
+
+ 236 +
+
+ +
+
+
/// ```
+
+
+
+ 237 +
+
+ +
+
+
#[test]
+
+
+
+ 238 +
+
+ 1 +
+
+
fn reduce_solve_xyz() {
+
+
+
+ 239 +
+
+ 1 +
+
+
    println!("Rules: {:?}", get_rules());
+
+
+
+ 240 +
+
+ 1 +
+
+
    let sum_constants = get_rule_by_name("sum_constants").unwrap();
+
+
+
+ 241 +
+
+ 1 +
+
+
    let unwrap_sum = get_rule_by_name("unwrap_sum").unwrap();
+
+
+
+ 242 +
+
+ 1 +
+
+
    let lt_to_ineq = get_rule_by_name("lt_to_ineq").unwrap();
+
+
+
+ 243 +
+
+ 1 +
+
+
    let sum_leq_to_sumleq = get_rule_by_name("sum_leq_to_sumleq").unwrap();
+
+
+
+ 244 +
+
+ 1 +
+
+

+            
+
+
+ 245 +
+
+ 1 +
+
+
    // 2 + 3 - 1
+
+
+
+ 246 +
+
+ 1 +
+
+
    let mut expr1 = Expression::Sum(
+
+
+
+ 247 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 248 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 249 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Int(2)),
+
+
+
+ 250 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Int(3)),
+
+
+
+ 251 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Int(-1)),
+
+
+
+ 252 +
+
+ 1 +
+
+
        ],
+
+
+
+ 253 +
+
+ 1 +
+
+
    );
+
+
+
+ 254 +
+
+ 1 +
+
+

+            
+
+
+ 255 +
+
+ 1 +
+
+
    expr1 = sum_constants
+
+
+
+ 256 +
+
+ 1 +
+
+
        .apply(&expr1, &Model::new_empty(Default::default()))
+
+
+
+ 257 +
+
+ 1 +
+
+
        .unwrap()
+
+
+
+ 258 +
+
+ 1 +
+
+
        .new_expression;
+
+
+
+ 259 +
+
+ 1 +
+
+
    expr1 = unwrap_sum
+
+
+
+ 260 +
+
+ 1 +
+
+
        .apply(&expr1, &Model::new_empty(Default::default()))
+
+
+
+ 261 +
+
+ 1 +
+
+
        .unwrap()
+
+
+
+ 262 +
+
+ 1 +
+
+
        .new_expression;
+
+
+
+ 263 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 264 +
+
+ 1 +
+
+
        expr1,
+
+
+
+ 265 +
+
+ 1 +
+
+
        Expression::Constant(Metadata::new(), Constant::Int(4))
+
+
+
+ 266 +
+
+ 1 +
+
+
    );
+
+
+
+ 267 +
+
+ +
+
+

+            
+
+
+ 268 +
+
+ +
+
+
    // a + b + c = 4
+
+
+
+ 269 +
+
+ 1 +
+
+
    expr1 = Expression::Leq(
+
+
+
+ 270 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 271 +
+
+ 1 +
+
+
        Box::new(Expression::Sum(
+
+
+
+ 272 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 273 +
+
+ 1 +
+
+
            vec![
+
+
+
+ 274 +
+
+ 1 +
+
+
                Expression::Reference(Metadata::new(), Name::UserName(String::from("a"))),
+
+
+
+ 275 +
+
+ 1 +
+
+
                Expression::Reference(Metadata::new(), Name::UserName(String::from("b"))),
+
+
+
+ 276 +
+
+ 1 +
+
+
                Expression::Reference(Metadata::new(), Name::UserName(String::from("c"))),
+
+
+
+ 277 +
+
+ 1 +
+
+
            ],
+
+
+
+ 278 +
+
+ 1 +
+
+
        )),
+
+
+
+ 279 +
+
+ 1 +
+
+
        Box::new(expr1),
+
+
+
+ 280 +
+
+ 1 +
+
+
    );
+
+
+
+ 281 +
+
+ 1 +
+
+
    expr1 = sum_leq_to_sumleq
+
+
+
+ 282 +
+
+ 1 +
+
+
        .apply(&expr1, &Model::new_empty(Default::default()))
+
+
+
+ 283 +
+
+ 1 +
+
+
        .unwrap()
+
+
+
+ 284 +
+
+ 1 +
+
+
        .new_expression;
+
+
+
+ 285 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 286 +
+
+ 1 +
+
+
        expr1,
+
+
+
+ 287 +
+
+ 1 +
+
+
        Expression::SumLeq(
+
+
+
+ 288 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 289 +
+
+ 1 +
+
+
            vec![
+
+
+
+ 290 +
+
+ 1 +
+
+
                Expression::Reference(Metadata::new(), Name::UserName(String::from("a"))),
+
+
+
+ 291 +
+
+ 1 +
+
+
                Expression::Reference(Metadata::new(), Name::UserName(String::from("b"))),
+
+
+
+ 292 +
+
+ 1 +
+
+
                Expression::Reference(Metadata::new(), Name::UserName(String::from("c"))),
+
+
+
+ 293 +
+
+ 1 +
+
+
            ],
+
+
+
+ 294 +
+
+ 1 +
+
+
            Box::new(Expression::Constant(Metadata::new(), Constant::Int(4)))
+
+
+
+ 295 +
+
+ 1 +
+
+
        )
+
+
+
+ 296 +
+
+ 1 +
+
+
    );
+
+
+
+ 297 +
+
+ +
+
+

+            
+
+
+ 298 +
+
+ +
+
+
    // a < b
+
+
+
+ 299 +
+
+ 1 +
+
+
    let mut expr2 = Expression::Lt(
+
+
+
+ 300 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 301 +
+
+ 1 +
+
+
        Box::new(Expression::Reference(
+
+
+
+ 302 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 303 +
+
+ 1 +
+
+
            Name::UserName(String::from("a")),
+
+
+
+ 304 +
+
+ 1 +
+
+
        )),
+
+
+
+ 305 +
+
+ 1 +
+
+
        Box::new(Expression::Reference(
+
+
+
+ 306 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 307 +
+
+ 1 +
+
+
            Name::UserName(String::from("b")),
+
+
+
+ 308 +
+
+ 1 +
+
+
        )),
+
+
+
+ 309 +
+
+ 1 +
+
+
    );
+
+
+
+ 310 +
+
+ 1 +
+
+
    expr2 = lt_to_ineq
+
+
+
+ 311 +
+
+ 1 +
+
+
        .apply(&expr2, &Model::new_empty(Default::default()))
+
+
+
+ 312 +
+
+ 1 +
+
+
        .unwrap()
+
+
+
+ 313 +
+
+ 1 +
+
+
        .new_expression;
+
+
+
+ 314 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 315 +
+
+ 1 +
+
+
        expr2,
+
+
+
+ 316 +
+
+ 1 +
+
+
        Expression::Ineq(
+
+
+
+ 317 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 318 +
+
+ 1 +
+
+
            Box::new(Expression::Reference(
+
+
+
+ 319 +
+
+ 1 +
+
+
                Metadata::new(),
+
+
+
+ 320 +
+
+ 1 +
+
+
                Name::UserName(String::from("a"))
+
+
+
+ 321 +
+
+ 1 +
+
+
            )),
+
+
+
+ 322 +
+
+ 1 +
+
+
            Box::new(Expression::Reference(
+
+
+
+ 323 +
+
+ 1 +
+
+
                Metadata::new(),
+
+
+
+ 324 +
+
+ 1 +
+
+
                Name::UserName(String::from("b"))
+
+
+
+ 325 +
+
+ 1 +
+
+
            )),
+
+
+
+ 326 +
+
+ 1 +
+
+
            Box::new(Expression::Constant(Metadata::new(), Constant::Int(-1)))
+
+
+
+ 327 +
+
+ 1 +
+
+
        )
+
+
+
+ 328 +
+
+ 1 +
+
+
    );
+
+
+
+ 329 +
+
+ +
+
+

+            
+
+
+ 330 +
+
+ 1 +
+
+
    let mut model = Model::new(
+
+
+
+ 331 +
+
+ 1 +
+
+
        HashMap::new(),
+
+
+
+ 332 +
+
+ 1 +
+
+
        Expression::And(Metadata::new(), vec![expr1, expr2]),
+
+
+
+ 333 +
+
+ 1 +
+
+
        Default::default(),
+
+
+
+ 334 +
+
+ 1 +
+
+
    );
+
+
+
+ 335 +
+
+ 1 +
+
+
    model.variables.insert(
+
+
+
+ 336 +
+
+ 1 +
+
+
        Name::UserName(String::from("a")),
+
+
+
+ 337 +
+
+ 1 +
+
+
        DecisionVariable {
+
+
+
+ 338 +
+
+ 1 +
+
+
            domain: Domain::IntDomain(vec![Range::Bounded(1, 3)]),
+
+
+
+ 339 +
+
+ 1 +
+
+
        },
+
+
+
+ 340 +
+
+ 1 +
+
+
    );
+
+
+
+ 341 +
+
+ 1 +
+
+
    model.variables.insert(
+
+
+
+ 342 +
+
+ 1 +
+
+
        Name::UserName(String::from("b")),
+
+
+
+ 343 +
+
+ 1 +
+
+
        DecisionVariable {
+
+
+
+ 344 +
+
+ 1 +
+
+
            domain: Domain::IntDomain(vec![Range::Bounded(1, 3)]),
+
+
+
+ 345 +
+
+ 1 +
+
+
        },
+
+
+
+ 346 +
+
+ 1 +
+
+
    );
+
+
+
+ 347 +
+
+ 1 +
+
+
    model.variables.insert(
+
+
+
+ 348 +
+
+ 1 +
+
+
        Name::UserName(String::from("c")),
+
+
+
+ 349 +
+
+ 1 +
+
+
        DecisionVariable {
+
+
+
+ 350 +
+
+ 1 +
+
+
            domain: Domain::IntDomain(vec![Range::Bounded(1, 3)]),
+
+
+
+ 351 +
+
+ 1 +
+
+
        },
+
+
+
+ 352 +
+
+ 1 +
+
+
    );
+
+
+
+ 353 +
+
+ 1 +
+
+

+            
+
+
+ 354 +
+
+ 1 +
+
+
    let solver: Solver<adaptors::Minion> = Solver::new(adaptors::Minion::new());
+
+
+
+ 355 +
+
+ 1 +
+
+
    let solver = solver.load_model(model).unwrap();
+
+
+
+ 356 +
+
+ 1 +
+
+
    solver.solve(Box::new(|_| true)).unwrap();
+
+
+
+ 357 +
+
+ 1 +
+
+
}
+
+
+
+ 358 +
+
+ +
+
+

+            
+
+
+ 359 +
+
+ +
+
+
#[test]
+
+
+
+ 360 +
+
+ 1 +
+
+
fn rule_remove_double_negation() {
+
+
+
+ 361 +
+
+ 1 +
+
+
    let remove_double_negation = get_rule_by_name("remove_double_negation").unwrap();
+
+
+
+ 362 +
+
+ 1 +
+
+

+            
+
+
+ 363 +
+
+ 1 +
+
+
    let mut expr = Expression::Not(
+
+
+
+ 364 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 365 +
+
+ 1 +
+
+
        Box::new(Expression::Not(
+
+
+
+ 366 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 367 +
+
+ 1 +
+
+
            Box::new(Expression::Constant(Metadata::new(), Constant::Bool(true))),
+
+
+
+ 368 +
+
+ 1 +
+
+
        )),
+
+
+
+ 369 +
+
+ 1 +
+
+
    );
+
+
+
+ 370 +
+
+ 1 +
+
+

+            
+
+
+ 371 +
+
+ 1 +
+
+
    expr = remove_double_negation
+
+
+
+ 372 +
+
+ 1 +
+
+
        .apply(&expr, &Model::new_empty(Default::default()))
+
+
+
+ 373 +
+
+ 1 +
+
+
        .unwrap()
+
+
+
+ 374 +
+
+ 1 +
+
+
        .new_expression;
+
+
+
+ 375 +
+
+ 1 +
+
+

+            
+
+
+ 376 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 377 +
+
+ 1 +
+
+
        expr,
+
+
+
+ 378 +
+
+ 1 +
+
+
        Expression::Constant(Metadata::new(), Constant::Bool(true))
+
+
+
+ 379 +
+
+ 1 +
+
+
    );
+
+
+
+ 380 +
+
+ 1 +
+
+
}
+
+
+
+ 381 +
+
+ +
+
+

+            
+
+
+ 382 +
+
+ +
+
+
#[test]
+
+
+
+ 383 +
+
+ 1 +
+
+
fn rule_unwrap_nested_or() {
+
+
+
+ 384 +
+
+ 1 +
+
+
    let unwrap_nested_or = get_rule_by_name("unwrap_nested_or").unwrap();
+
+
+
+ 385 +
+
+ 1 +
+
+

+            
+
+
+ 386 +
+
+ 1 +
+
+
    let mut expr = Expression::Or(
+
+
+
+ 387 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 388 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 389 +
+
+ 1 +
+
+
            Expression::Or(
+
+
+
+ 390 +
+
+ 1 +
+
+
                Metadata::new(),
+
+
+
+ 391 +
+
+ 1 +
+
+
                vec![
+
+
+
+ 392 +
+
+ 1 +
+
+
                    Expression::Constant(Metadata::new(), Constant::Bool(true)),
+
+
+
+ 393 +
+
+ 1 +
+
+
                    Expression::Constant(Metadata::new(), Constant::Bool(false)),
+
+
+
+ 394 +
+
+ 1 +
+
+
                ],
+
+
+
+ 395 +
+
+ 1 +
+
+
            ),
+
+
+
+ 396 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Bool(true)),
+
+
+
+ 397 +
+
+ 1 +
+
+
        ],
+
+
+
+ 398 +
+
+ 1 +
+
+
    );
+
+
+
+ 399 +
+
+ 1 +
+
+

+            
+
+
+ 400 +
+
+ 1 +
+
+
    expr = unwrap_nested_or
+
+
+
+ 401 +
+
+ 1 +
+
+
        .apply(&expr, &Model::new_empty(Default::default()))
+
+
+
+ 402 +
+
+ 1 +
+
+
        .unwrap()
+
+
+
+ 403 +
+
+ 1 +
+
+
        .new_expression;
+
+
+
+ 404 +
+
+ 1 +
+
+

+            
+
+
+ 405 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 406 +
+
+ 1 +
+
+
        expr,
+
+
+
+ 407 +
+
+ 1 +
+
+
        Expression::Or(
+
+
+
+ 408 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 409 +
+
+ 1 +
+
+
            vec![
+
+
+
+ 410 +
+
+ 1 +
+
+
                Expression::Constant(Metadata::new(), Constant::Bool(true)),
+
+
+
+ 411 +
+
+ 1 +
+
+
                Expression::Constant(Metadata::new(), Constant::Bool(false)),
+
+
+
+ 412 +
+
+ 1 +
+
+
                Expression::Constant(Metadata::new(), Constant::Bool(true)),
+
+
+
+ 413 +
+
+ 1 +
+
+
            ]
+
+
+
+ 414 +
+
+ 1 +
+
+
        )
+
+
+
+ 415 +
+
+ 1 +
+
+
    );
+
+
+
+ 416 +
+
+ 1 +
+
+
}
+
+
+
+ 417 +
+
+ +
+
+

+            
+
+
+ 418 +
+
+ +
+
+
#[test]
+
+
+
+ 419 +
+
+ 1 +
+
+
fn rule_unwrap_nested_and() {
+
+
+
+ 420 +
+
+ 1 +
+
+
    let unwrap_nested_and = get_rule_by_name("unwrap_nested_and").unwrap();
+
+
+
+ 421 +
+
+ 1 +
+
+

+            
+
+
+ 422 +
+
+ 1 +
+
+
    let mut expr = Expression::And(
+
+
+
+ 423 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 424 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 425 +
+
+ 1 +
+
+
            Expression::And(
+
+
+
+ 426 +
+
+ 1 +
+
+
                Metadata::new(),
+
+
+
+ 427 +
+
+ 1 +
+
+
                vec![
+
+
+
+ 428 +
+
+ 1 +
+
+
                    Expression::Constant(Metadata::new(), Constant::Bool(true)),
+
+
+
+ 429 +
+
+ 1 +
+
+
                    Expression::Constant(Metadata::new(), Constant::Bool(false)),
+
+
+
+ 430 +
+
+ 1 +
+
+
                ],
+
+
+
+ 431 +
+
+ 1 +
+
+
            ),
+
+
+
+ 432 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Bool(true)),
+
+
+
+ 433 +
+
+ 1 +
+
+
        ],
+
+
+
+ 434 +
+
+ 1 +
+
+
    );
+
+
+
+ 435 +
+
+ 1 +
+
+

+            
+
+
+ 436 +
+
+ 1 +
+
+
    expr = unwrap_nested_and
+
+
+
+ 437 +
+
+ 1 +
+
+
        .apply(&expr, &Model::new_empty(Default::default()))
+
+
+
+ 438 +
+
+ 1 +
+
+
        .unwrap()
+
+
+
+ 439 +
+
+ 1 +
+
+
        .new_expression;
+
+
+
+ 440 +
+
+ 1 +
+
+

+            
+
+
+ 441 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 442 +
+
+ 1 +
+
+
        expr,
+
+
+
+ 443 +
+
+ 1 +
+
+
        Expression::And(
+
+
+
+ 444 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 445 +
+
+ 1 +
+
+
            vec![
+
+
+
+ 446 +
+
+ 1 +
+
+
                Expression::Constant(Metadata::new(), Constant::Bool(true)),
+
+
+
+ 447 +
+
+ 1 +
+
+
                Expression::Constant(Metadata::new(), Constant::Bool(false)),
+
+
+
+ 448 +
+
+ 1 +
+
+
                Expression::Constant(Metadata::new(), Constant::Bool(true)),
+
+
+
+ 449 +
+
+ 1 +
+
+
            ]
+
+
+
+ 450 +
+
+ 1 +
+
+
        )
+
+
+
+ 451 +
+
+ 1 +
+
+
    );
+
+
+
+ 452 +
+
+ 1 +
+
+
}
+
+
+
+ 453 +
+
+ +
+
+

+            
+
+
+ 454 +
+
+ +
+
+
#[test]
+
+
+
+ 455 +
+
+ 1 +
+
+
fn unwrap_nested_or_not_changed() {
+
+
+
+ 456 +
+
+ 1 +
+
+
    let unwrap_nested_or = get_rule_by_name("unwrap_nested_or").unwrap();
+
+
+
+ 457 +
+
+ 1 +
+
+

+            
+
+
+ 458 +
+
+ 1 +
+
+
    let expr = Expression::Or(
+
+
+
+ 459 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 460 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 461 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Bool(true)),
+
+
+
+ 462 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Bool(false)),
+
+
+
+ 463 +
+
+ 1 +
+
+
        ],
+
+
+
+ 464 +
+
+ 1 +
+
+
    );
+
+
+
+ 465 +
+
+ 1 +
+
+

+            
+
+
+ 466 +
+
+ 1 +
+
+
    let result = unwrap_nested_or.apply(&expr, &Model::new_empty(Default::default()));
+
+
+
+ 467 +
+
+ 1 +
+
+

+            
+
+
+ 468 +
+
+ 1 +
+
+
    assert!(result.is_err());
+
+
+
+ 469 +
+
+ 1 +
+
+
}
+
+
+
+ 470 +
+
+ +
+
+

+            
+
+
+ 471 +
+
+ +
+
+
#[test]
+
+
+
+ 472 +
+
+ 1 +
+
+
fn unwrap_nested_and_not_changed() {
+
+
+
+ 473 +
+
+ 1 +
+
+
    let unwrap_nested_and = get_rule_by_name("unwrap_nested_and").unwrap();
+
+
+
+ 474 +
+
+ 1 +
+
+

+            
+
+
+ 475 +
+
+ 1 +
+
+
    let expr = Expression::And(
+
+
+
+ 476 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 477 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 478 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Bool(true)),
+
+
+
+ 479 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Bool(false)),
+
+
+
+ 480 +
+
+ 1 +
+
+
        ],
+
+
+
+ 481 +
+
+ 1 +
+
+
    );
+
+
+
+ 482 +
+
+ 1 +
+
+

+            
+
+
+ 483 +
+
+ 1 +
+
+
    let result = unwrap_nested_and.apply(&expr, &Model::new_empty(Default::default()));
+
+
+
+ 484 +
+
+ 1 +
+
+

+            
+
+
+ 485 +
+
+ 1 +
+
+
    assert!(result.is_err());
+
+
+
+ 486 +
+
+ 1 +
+
+
}
+
+
+
+ 487 +
+
+ +
+
+

+            
+
+
+ 488 +
+
+ +
+
+
#[test]
+
+
+
+ 489 +
+
+ 1 +
+
+
fn remove_trivial_and_or() {
+
+
+
+ 490 +
+
+ 1 +
+
+
    let remove_trivial_and = get_rule_by_name("remove_trivial_and").unwrap();
+
+
+
+ 491 +
+
+ 1 +
+
+
    let remove_trivial_or = get_rule_by_name("remove_trivial_or").unwrap();
+
+
+
+ 492 +
+
+ 1 +
+
+

+            
+
+
+ 493 +
+
+ 1 +
+
+
    let mut expr_and = Expression::And(
+
+
+
+ 494 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 495 +
+
+ 1 +
+
+
        vec![Expression::Constant(Metadata::new(), Constant::Bool(true))],
+
+
+
+ 496 +
+
+ 1 +
+
+
    );
+
+
+
+ 497 +
+
+ 1 +
+
+
    let mut expr_or = Expression::Or(
+
+
+
+ 498 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 499 +
+
+ 1 +
+
+
        vec![Expression::Constant(Metadata::new(), Constant::Bool(false))],
+
+
+
+ 500 +
+
+ 1 +
+
+
    );
+
+
+
+ 501 +
+
+ 1 +
+
+

+            
+
+
+ 502 +
+
+ 1 +
+
+
    expr_and = remove_trivial_and
+
+
+
+ 503 +
+
+ 1 +
+
+
        .apply(&expr_and, &Model::new_empty(Default::default()))
+
+
+
+ 504 +
+
+ 1 +
+
+
        .unwrap()
+
+
+
+ 505 +
+
+ 1 +
+
+
        .new_expression;
+
+
+
+ 506 +
+
+ 1 +
+
+
    expr_or = remove_trivial_or
+
+
+
+ 507 +
+
+ 1 +
+
+
        .apply(&expr_or, &Model::new_empty(Default::default()))
+
+
+
+ 508 +
+
+ 1 +
+
+
        .unwrap()
+
+
+
+ 509 +
+
+ 1 +
+
+
        .new_expression;
+
+
+
+ 510 +
+
+ 1 +
+
+

+            
+
+
+ 511 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 512 +
+
+ 1 +
+
+
        expr_and,
+
+
+
+ 513 +
+
+ 1 +
+
+
        Expression::Constant(Metadata::new(), Constant::Bool(true))
+
+
+
+ 514 +
+
+ 1 +
+
+
    );
+
+
+
+ 515 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 516 +
+
+ 1 +
+
+
        expr_or,
+
+
+
+ 517 +
+
+ 1 +
+
+
        Expression::Constant(Metadata::new(), Constant::Bool(false))
+
+
+
+ 518 +
+
+ 1 +
+
+
    );
+
+
+
+ 519 +
+
+ 1 +
+
+
}
+
+
+
+ 520 +
+
+ +
+
+

+            
+
+
+ 521 +
+
+ +
+
+
#[test]
+
+
+
+ 522 +
+
+ 1 +
+
+
fn rule_remove_constants_from_or() {
+
+
+
+ 523 +
+
+ 1 +
+
+
    let remove_constants_from_or = get_rule_by_name("remove_constants_from_or").unwrap();
+
+
+
+ 524 +
+
+ 1 +
+
+

+            
+
+
+ 525 +
+
+ 1 +
+
+
    let mut expr = Expression::Or(
+
+
+
+ 526 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 527 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 528 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Bool(true)),
+
+
+
+ 529 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Bool(false)),
+
+
+
+ 530 +
+
+ 1 +
+
+
            Expression::Reference(Metadata::new(), Name::UserName(String::from("a"))),
+
+
+
+ 531 +
+
+ 1 +
+
+
        ],
+
+
+
+ 532 +
+
+ 1 +
+
+
    );
+
+
+
+ 533 +
+
+ 1 +
+
+

+            
+
+
+ 534 +
+
+ 1 +
+
+
    expr = remove_constants_from_or
+
+
+
+ 535 +
+
+ 1 +
+
+
        .apply(&expr, &Model::new_empty(Default::default()))
+
+
+
+ 536 +
+
+ 1 +
+
+
        .unwrap()
+
+
+
+ 537 +
+
+ 1 +
+
+
        .new_expression;
+
+
+
+ 538 +
+
+ 1 +
+
+

+            
+
+
+ 539 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 540 +
+
+ 1 +
+
+
        expr,
+
+
+
+ 541 +
+
+ 1 +
+
+
        Expression::Constant(Metadata::new(), Constant::Bool(true))
+
+
+
+ 542 +
+
+ 1 +
+
+
    );
+
+
+
+ 543 +
+
+ 1 +
+
+
}
+
+
+
+ 544 +
+
+ +
+
+

+            
+
+
+ 545 +
+
+ +
+
+
#[test]
+
+
+
+ 546 +
+
+ 1 +
+
+
fn rule_remove_constants_from_and() {
+
+
+
+ 547 +
+
+ 1 +
+
+
    let remove_constants_from_and = get_rule_by_name("remove_constants_from_and").unwrap();
+
+
+
+ 548 +
+
+ 1 +
+
+

+            
+
+
+ 549 +
+
+ 1 +
+
+
    let mut expr = Expression::And(
+
+
+
+ 550 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 551 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 552 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Bool(true)),
+
+
+
+ 553 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Bool(false)),
+
+
+
+ 554 +
+
+ 1 +
+
+
            Expression::Reference(Metadata::new(), Name::UserName(String::from("a"))),
+
+
+
+ 555 +
+
+ 1 +
+
+
        ],
+
+
+
+ 556 +
+
+ 1 +
+
+
    );
+
+
+
+ 557 +
+
+ 1 +
+
+

+            
+
+
+ 558 +
+
+ 1 +
+
+
    expr = remove_constants_from_and
+
+
+
+ 559 +
+
+ 1 +
+
+
        .apply(&expr, &Model::new_empty(Default::default()))
+
+
+
+ 560 +
+
+ 1 +
+
+
        .unwrap()
+
+
+
+ 561 +
+
+ 1 +
+
+
        .new_expression;
+
+
+
+ 562 +
+
+ 1 +
+
+

+            
+
+
+ 563 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 564 +
+
+ 1 +
+
+
        expr,
+
+
+
+ 565 +
+
+ 1 +
+
+
        Expression::Constant(Metadata::new(), Constant::Bool(false))
+
+
+
+ 566 +
+
+ 1 +
+
+
    );
+
+
+
+ 567 +
+
+ 1 +
+
+
}
+
+
+
+ 568 +
+
+ +
+
+

+            
+
+
+ 569 +
+
+ +
+
+
#[test]
+
+
+
+ 570 +
+
+ 1 +
+
+
fn remove_constants_from_or_not_changed() {
+
+
+
+ 571 +
+
+ 1 +
+
+
    let remove_constants_from_or = get_rule_by_name("remove_constants_from_or").unwrap();
+
+
+
+ 572 +
+
+ 1 +
+
+

+            
+
+
+ 573 +
+
+ 1 +
+
+
    let expr = Expression::Or(
+
+
+
+ 574 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 575 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 576 +
+
+ 1 +
+
+
            Expression::Reference(Metadata::new(), Name::UserName(String::from("a"))),
+
+
+
+ 577 +
+
+ 1 +
+
+
            Expression::Reference(Metadata::new(), Name::UserName(String::from("b"))),
+
+
+
+ 578 +
+
+ 1 +
+
+
        ],
+
+
+
+ 579 +
+
+ 1 +
+
+
    );
+
+
+
+ 580 +
+
+ 1 +
+
+

+            
+
+
+ 581 +
+
+ 1 +
+
+
    let result = remove_constants_from_or.apply(&expr, &Model::new_empty(Default::default()));
+
+
+
+ 582 +
+
+ 1 +
+
+

+            
+
+
+ 583 +
+
+ 1 +
+
+
    assert!(result.is_err());
+
+
+
+ 584 +
+
+ 1 +
+
+
}
+
+
+
+ 585 +
+
+ +
+
+

+            
+
+
+ 586 +
+
+ +
+
+
#[test]
+
+
+
+ 587 +
+
+ 1 +
+
+
fn remove_constants_from_and_not_changed() {
+
+
+
+ 588 +
+
+ 1 +
+
+
    let remove_constants_from_and = get_rule_by_name("remove_constants_from_and").unwrap();
+
+
+
+ 589 +
+
+ 1 +
+
+

+            
+
+
+ 590 +
+
+ 1 +
+
+
    let expr = Expression::And(
+
+
+
+ 591 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 592 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 593 +
+
+ 1 +
+
+
            Expression::Reference(Metadata::new(), Name::UserName(String::from("a"))),
+
+
+
+ 594 +
+
+ 1 +
+
+
            Expression::Reference(Metadata::new(), Name::UserName(String::from("b"))),
+
+
+
+ 595 +
+
+ 1 +
+
+
        ],
+
+
+
+ 596 +
+
+ 1 +
+
+
    );
+
+
+
+ 597 +
+
+ 1 +
+
+

+            
+
+
+ 598 +
+
+ 1 +
+
+
    let result = remove_constants_from_and.apply(&expr, &Model::new_empty(Default::default()));
+
+
+
+ 599 +
+
+ 1 +
+
+

+            
+
+
+ 600 +
+
+ 1 +
+
+
    assert!(result.is_err());
+
+
+
+ 601 +
+
+ 1 +
+
+
}
+
+
+
+ 602 +
+
+ +
+
+

+            
+
+
+ 603 +
+
+ +
+
+
#[test]
+
+
+
+ 604 +
+
+ 1 +
+
+
fn rule_distribute_not_over_and() {
+
+
+
+ 605 +
+
+ 1 +
+
+
    let distribute_not_over_and = get_rule_by_name("distribute_not_over_and").unwrap();
+
+
+
+ 606 +
+
+ 1 +
+
+

+            
+
+
+ 607 +
+
+ 1 +
+
+
    let mut expr = Expression::Not(
+
+
+
+ 608 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 609 +
+
+ 1 +
+
+
        Box::new(Expression::And(
+
+
+
+ 610 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 611 +
+
+ 1 +
+
+
            vec![
+
+
+
+ 612 +
+
+ 1 +
+
+
                Expression::Reference(Metadata::new(), Name::UserName(String::from("a"))),
+
+
+
+ 613 +
+
+ 1 +
+
+
                Expression::Reference(Metadata::new(), Name::UserName(String::from("b"))),
+
+
+
+ 614 +
+
+ 1 +
+
+
            ],
+
+
+
+ 615 +
+
+ 1 +
+
+
        )),
+
+
+
+ 616 +
+
+ 1 +
+
+
    );
+
+
+
+ 617 +
+
+ 1 +
+
+

+            
+
+
+ 618 +
+
+ 1 +
+
+
    expr = distribute_not_over_and
+
+
+
+ 619 +
+
+ 1 +
+
+
        .apply(&expr, &Model::new_empty(Default::default()))
+
+
+
+ 620 +
+
+ 1 +
+
+
        .unwrap()
+
+
+
+ 621 +
+
+ 1 +
+
+
        .new_expression;
+
+
+
+ 622 +
+
+ 1 +
+
+

+            
+
+
+ 623 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 624 +
+
+ 1 +
+
+
        expr,
+
+
+
+ 625 +
+
+ 1 +
+
+
        Expression::Or(
+
+
+
+ 626 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 627 +
+
+ 1 +
+
+
            vec![
+
+
+
+ 628 +
+
+ 1 +
+
+
                Expression::Not(
+
+
+
+ 629 +
+
+ 1 +
+
+
                    Metadata::new(),
+
+
+
+ 630 +
+
+ 1 +
+
+
                    Box::new(Expression::Reference(
+
+
+
+ 631 +
+
+ 1 +
+
+
                        Metadata::new(),
+
+
+
+ 632 +
+
+ 1 +
+
+
                        Name::UserName(String::from("a"))
+
+
+
+ 633 +
+
+ 1 +
+
+
                    ))
+
+
+
+ 634 +
+
+ 1 +
+
+
                ),
+
+
+
+ 635 +
+
+ 1 +
+
+
                Expression::Not(
+
+
+
+ 636 +
+
+ 1 +
+
+
                    Metadata::new(),
+
+
+
+ 637 +
+
+ 1 +
+
+
                    Box::new(Expression::Reference(
+
+
+
+ 638 +
+
+ 1 +
+
+
                        Metadata::new(),
+
+
+
+ 639 +
+
+ 1 +
+
+
                        Name::UserName(String::from("b"))
+
+
+
+ 640 +
+
+ 1 +
+
+
                    ))
+
+
+
+ 641 +
+
+ 1 +
+
+
                ),
+
+
+
+ 642 +
+
+ 1 +
+
+
            ]
+
+
+
+ 643 +
+
+ 1 +
+
+
        )
+
+
+
+ 644 +
+
+ 1 +
+
+
    );
+
+
+
+ 645 +
+
+ 1 +
+
+
}
+
+
+
+ 646 +
+
+ +
+
+

+            
+
+
+ 647 +
+
+ +
+
+
#[test]
+
+
+
+ 648 +
+
+ 1 +
+
+
fn rule_distribute_not_over_or() {
+
+
+
+ 649 +
+
+ 1 +
+
+
    let distribute_not_over_or = get_rule_by_name("distribute_not_over_or").unwrap();
+
+
+
+ 650 +
+
+ 1 +
+
+

+            
+
+
+ 651 +
+
+ 1 +
+
+
    let mut expr = Expression::Not(
+
+
+
+ 652 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 653 +
+
+ 1 +
+
+
        Box::new(Expression::Or(
+
+
+
+ 654 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 655 +
+
+ 1 +
+
+
            vec![
+
+
+
+ 656 +
+
+ 1 +
+
+
                Expression::Reference(Metadata::new(), Name::UserName(String::from("a"))),
+
+
+
+ 657 +
+
+ 1 +
+
+
                Expression::Reference(Metadata::new(), Name::UserName(String::from("b"))),
+
+
+
+ 658 +
+
+ 1 +
+
+
            ],
+
+
+
+ 659 +
+
+ 1 +
+
+
        )),
+
+
+
+ 660 +
+
+ 1 +
+
+
    );
+
+
+
+ 661 +
+
+ 1 +
+
+

+            
+
+
+ 662 +
+
+ 1 +
+
+
    expr = distribute_not_over_or
+
+
+
+ 663 +
+
+ 1 +
+
+
        .apply(&expr, &Model::new_empty(Default::default()))
+
+
+
+ 664 +
+
+ 1 +
+
+
        .unwrap()
+
+
+
+ 665 +
+
+ 1 +
+
+
        .new_expression;
+
+
+
+ 666 +
+
+ 1 +
+
+

+            
+
+
+ 667 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 668 +
+
+ 1 +
+
+
        expr,
+
+
+
+ 669 +
+
+ 1 +
+
+
        Expression::And(
+
+
+
+ 670 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 671 +
+
+ 1 +
+
+
            vec![
+
+
+
+ 672 +
+
+ 1 +
+
+
                Expression::Not(
+
+
+
+ 673 +
+
+ 1 +
+
+
                    Metadata::new(),
+
+
+
+ 674 +
+
+ 1 +
+
+
                    Box::new(Expression::Reference(
+
+
+
+ 675 +
+
+ 1 +
+
+
                        Metadata::new(),
+
+
+
+ 676 +
+
+ 1 +
+
+
                        Name::UserName(String::from("a"))
+
+
+
+ 677 +
+
+ 1 +
+
+
                    ))
+
+
+
+ 678 +
+
+ 1 +
+
+
                ),
+
+
+
+ 679 +
+
+ 1 +
+
+
                Expression::Not(
+
+
+
+ 680 +
+
+ 1 +
+
+
                    Metadata::new(),
+
+
+
+ 681 +
+
+ 1 +
+
+
                    Box::new(Expression::Reference(
+
+
+
+ 682 +
+
+ 1 +
+
+
                        Metadata::new(),
+
+
+
+ 683 +
+
+ 1 +
+
+
                        Name::UserName(String::from("b"))
+
+
+
+ 684 +
+
+ 1 +
+
+
                    ))
+
+
+
+ 685 +
+
+ 1 +
+
+
                ),
+
+
+
+ 686 +
+
+ 1 +
+
+
            ]
+
+
+
+ 687 +
+
+ 1 +
+
+
        )
+
+
+
+ 688 +
+
+ 1 +
+
+
    );
+
+
+
+ 689 +
+
+ 1 +
+
+
}
+
+
+
+ 690 +
+
+ +
+
+

+            
+
+
+ 691 +
+
+ +
+
+
#[test]
+
+
+
+ 692 +
+
+ 1 +
+
+
fn rule_distribute_not_over_and_not_changed() {
+
+
+
+ 693 +
+
+ 1 +
+
+
    let distribute_not_over_and = get_rule_by_name("distribute_not_over_and").unwrap();
+
+
+
+ 694 +
+
+ 1 +
+
+

+            
+
+
+ 695 +
+
+ 1 +
+
+
    let expr = Expression::Not(
+
+
+
+ 696 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 697 +
+
+ 1 +
+
+
        Box::new(Expression::Reference(
+
+
+
+ 698 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 699 +
+
+ 1 +
+
+
            Name::UserName(String::from("a")),
+
+
+
+ 700 +
+
+ 1 +
+
+
        )),
+
+
+
+ 701 +
+
+ 1 +
+
+
    );
+
+
+
+ 702 +
+
+ 1 +
+
+

+            
+
+
+ 703 +
+
+ 1 +
+
+
    let result = distribute_not_over_and.apply(&expr, &Model::new_empty(Default::default()));
+
+
+
+ 704 +
+
+ 1 +
+
+

+            
+
+
+ 705 +
+
+ 1 +
+
+
    assert!(result.is_err());
+
+
+
+ 706 +
+
+ 1 +
+
+
}
+
+
+
+ 707 +
+
+ +
+
+

+            
+
+
+ 708 +
+
+ +
+
+
#[test]
+
+
+
+ 709 +
+
+ 1 +
+
+
fn rule_distribute_not_over_or_not_changed() {
+
+
+
+ 710 +
+
+ 1 +
+
+
    let distribute_not_over_or = get_rule_by_name("distribute_not_over_or").unwrap();
+
+
+
+ 711 +
+
+ 1 +
+
+

+            
+
+
+ 712 +
+
+ 1 +
+
+
    let expr = Expression::Not(
+
+
+
+ 713 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 714 +
+
+ 1 +
+
+
        Box::new(Expression::Reference(
+
+
+
+ 715 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 716 +
+
+ 1 +
+
+
            Name::UserName(String::from("a")),
+
+
+
+ 717 +
+
+ 1 +
+
+
        )),
+
+
+
+ 718 +
+
+ 1 +
+
+
    );
+
+
+
+ 719 +
+
+ 1 +
+
+

+            
+
+
+ 720 +
+
+ 1 +
+
+
    let result = distribute_not_over_or.apply(&expr, &Model::new_empty(Default::default()));
+
+
+
+ 721 +
+
+ 1 +
+
+

+            
+
+
+ 722 +
+
+ 1 +
+
+
    assert!(result.is_err());
+
+
+
+ 723 +
+
+ 1 +
+
+
}
+
+
+
+ 724 +
+
+ +
+
+

+            
+
+
+ 725 +
+
+ +
+
+
#[test]
+
+
+
+ 726 +
+
+ 1 +
+
+
fn rule_distribute_or_over_and() {
+
+
+
+ 727 +
+
+ 1 +
+
+
    let distribute_or_over_and = get_rule_by_name("distribute_or_over_and").unwrap();
+
+
+
+ 728 +
+
+ 1 +
+
+

+            
+
+
+ 729 +
+
+ 1 +
+
+
    let expr = Expression::Or(
+
+
+
+ 730 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 731 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 732 +
+
+ 1 +
+
+
            Expression::And(
+
+
+
+ 733 +
+
+ 1 +
+
+
                Metadata::new(),
+
+
+
+ 734 +
+
+ 1 +
+
+
                vec![
+
+
+
+ 735 +
+
+ 1 +
+
+
                    Expression::Reference(Metadata::new(), Name::MachineName(1)),
+
+
+
+ 736 +
+
+ 1 +
+
+
                    Expression::Reference(Metadata::new(), Name::MachineName(2)),
+
+
+
+ 737 +
+
+ 1 +
+
+
                ],
+
+
+
+ 738 +
+
+ 1 +
+
+
            ),
+
+
+
+ 739 +
+
+ 1 +
+
+
            Expression::Reference(Metadata::new(), Name::MachineName(3)),
+
+
+
+ 740 +
+
+ 1 +
+
+
        ],
+
+
+
+ 741 +
+
+ 1 +
+
+
    );
+
+
+
+ 742 +
+
+ 1 +
+
+

+            
+
+
+ 743 +
+
+ 1 +
+
+
    let red = distribute_or_over_and
+
+
+
+ 744 +
+
+ 1 +
+
+
        .apply(&expr, &Model::new_empty(Default::default()))
+
+
+
+ 745 +
+
+ 1 +
+
+
        .unwrap();
+
+
+
+ 746 +
+
+ 1 +
+
+

+            
+
+
+ 747 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 748 +
+
+ 1 +
+
+
        red.new_expression,
+
+
+
+ 749 +
+
+ 1 +
+
+
        Expression::And(
+
+
+
+ 750 +
+
+ 1 +
+
+
            Metadata::new(),
+
+
+
+ 751 +
+
+ 1 +
+
+
            vec![
+
+
+
+ 752 +
+
+ 1 +
+
+
                Expression::Or(
+
+
+
+ 753 +
+
+ 1 +
+
+
                    Metadata::new(),
+
+
+
+ 754 +
+
+ 1 +
+
+
                    vec![
+
+
+
+ 755 +
+
+ 1 +
+
+
                        Expression::Reference(Metadata::new(), Name::MachineName(3)),
+
+
+
+ 756 +
+
+ 1 +
+
+
                        Expression::Reference(Metadata::new(), Name::MachineName(1)),
+
+
+
+ 757 +
+
+ 1 +
+
+
                    ]
+
+
+
+ 758 +
+
+ 1 +
+
+
                ),
+
+
+
+ 759 +
+
+ 1 +
+
+
                Expression::Or(
+
+
+
+ 760 +
+
+ 1 +
+
+
                    Metadata::new(),
+
+
+
+ 761 +
+
+ 1 +
+
+
                    vec![
+
+
+
+ 762 +
+
+ 1 +
+
+
                        Expression::Reference(Metadata::new(), Name::MachineName(3)),
+
+
+
+ 763 +
+
+ 1 +
+
+
                        Expression::Reference(Metadata::new(), Name::MachineName(2)),
+
+
+
+ 764 +
+
+ 1 +
+
+
                    ]
+
+
+
+ 765 +
+
+ 1 +
+
+
                ),
+
+
+
+ 766 +
+
+ 1 +
+
+
            ]
+
+
+
+ 767 +
+
+ 1 +
+
+
        ),
+
+
+
+ 768 +
+
+ 1 +
+
+
    );
+
+
+
+ 769 +
+
+ 1 +
+
+
}
+
+
+
+ 770 +
+
+ +
+
+

+            
+
+
+ 771 +
+
+ +
+
+
// #[test]
+
+
+
+ 772 +
+
+ +
+
+
// fn rule_ensure_div() {
+
+
+
+ 773 +
+
+ +
+
+
//     let ensure_div = get_rule_by_name("ensure_div").unwrap();
+
+
+
+ 774 +
+
+ +
+
+

+            
+
+
+ 775 +
+
+ +
+
+
//     let expr = Expression::Div(
+
+
+
+ 776 +
+
+ +
+
+
//         Metadata::new(),
+
+
+
+ 777 +
+
+ +
+
+
//         Box::new(Expression::Reference(
+
+
+
+ 778 +
+
+ +
+
+
//             Metadata::new(),
+
+
+
+ 779 +
+
+ +
+
+
//             Name::UserName("a".to_string()),
+
+
+
+ 780 +
+
+ +
+
+
//         )),
+
+
+
+ 781 +
+
+ +
+
+
//         Box::new(Expression::Reference(
+
+
+
+ 782 +
+
+ +
+
+
//             Metadata::new(),
+
+
+
+ 783 +
+
+ +
+
+
//             Name::UserName("b".to_string()),
+
+
+
+ 784 +
+
+ +
+
+
//         )),
+
+
+
+ 785 +
+
+ +
+
+
//     );
+
+
+
+ 786 +
+
+ +
+
+

+            
+
+
+ 787 +
+
+ +
+
+
//     let red = ensure_div.apply(&expr, &Model::new_empty(Default::default())).unwrap();
+
+
+
+ 788 +
+
+ +
+
+

+            
+
+
+ 789 +
+
+ +
+
+
//     assert_eq!(
+
+
+
+ 790 +
+
+ +
+
+
//         red.new_expression,
+
+
+
+ 791 +
+
+ +
+
+
//         Expression::SafeDiv(
+
+
+
+ 792 +
+
+ +
+
+
//             Metadata::new(),
+
+
+
+ 793 +
+
+ +
+
+
//             Box::new(Expression::Reference(
+
+
+
+ 794 +
+
+ +
+
+
//                 Metadata::new(),
+
+
+
+ 795 +
+
+ +
+
+
//                 Name::UserName("a".to_string())
+
+
+
+ 796 +
+
+ +
+
+
//             )),
+
+
+
+ 797 +
+
+ +
+
+
//             Box::new(Expression::Reference(
+
+
+
+ 798 +
+
+ +
+
+
//                 Metadata::new(),
+
+
+
+ 799 +
+
+ +
+
+
//                 Name::UserName("b".to_string())
+
+
+
+ 800 +
+
+ +
+
+
//             )),
+
+
+
+ 801 +
+
+ +
+
+
//         ),
+
+
+
+ 802 +
+
+ +
+
+
//     );
+
+
+
+ 803 +
+
+ +
+
+
//     assert_eq!(
+
+
+
+ 804 +
+
+ +
+
+
//         red.new_top,
+
+
+
+ 805 +
+
+ +
+
+
//         Expression::Neq(
+
+
+
+ 806 +
+
+ +
+
+
//             Metadata::new(),
+
+
+
+ 807 +
+
+ +
+
+
//             Box::new(Expression::Reference(
+
+
+
+ 808 +
+
+ +
+
+
//                 Metadata::new(),
+
+
+
+ 809 +
+
+ +
+
+
//                 Name::UserName("b".to_string())
+
+
+
+ 810 +
+
+ +
+
+
//             )),
+
+
+
+ 811 +
+
+ +
+
+
//             Box::new(Expression::Constant(Metadata::new(), Constant::Int(0)))
+
+
+
+ 812 +
+
+ +
+
+
//         )
+
+
+
+ 813 +
+
+ +
+
+
//     );
+
+
+
+ 814 +
+
+ +
+
+
// }
+
+
+
+ 815 +
+
+ +
+
+

+            
+
+
+ 816 +
+
+ +
+
+
///
+
+
+
+ 817 +
+
+ +
+
+
/// Reduce and solve:
+
+
+
+ 818 +
+
+ +
+
+
/// ```text
+
+
+
+ 819 +
+
+ +
+
+
/// find a,b,c : int(1..3)
+
+
+
+ 820 +
+
+ +
+
+
/// such that a + b + c = 4
+
+
+
+ 821 +
+
+ +
+
+
/// such that a < b
+
+
+
+ 822 +
+
+ +
+
+
/// ```
+
+
+
+ 823 +
+
+ +
+
+
///
+
+
+
+ 824 +
+
+ +
+
+
/// This test uses the rewrite function to simplify the expression instead
+
+
+
+ 825 +
+
+ +
+
+
/// of applying the rules manually.
+
+
+
+ 826 +
+
+ +
+
+
#[test]
+
+
+
+ 827 +
+
+ 1 +
+
+
fn rewrite_solve_xyz() {
+
+
+
+ 828 +
+
+ 1 +
+
+
    println!("Rules: {:?}", get_rules());
+
+
+
+ 829 +
+
+ +
+
+

+            
+
+
+ 830 +
+
+ 1 +
+
+
    let rule_sets = match resolve_rule_sets(SolverFamily::Minion, &vec!["Constant"]) {
+
+
+
+ 831 +
+
+ 1 +
+
+
        Ok(rs) => rs,
+
+
+
+ 832 +
+
+ +
+
+
        Err(e) => {
+
+
+
+ 833 +
+
+ +
+
+
            eprintln!("Error resolving rule sets: {}", e);
+
+
+
+ 834 +
+
+ +
+
+
            exit(1);
+
+
+
+ 835 +
+
+ +
+
+
        }
+
+
+
+ 836 +
+
+ +
+
+
    };
+
+
+
+ 837 +
+
+ 1 +
+
+
    println!("Rule sets: {:?}", rule_sets);
+
+
+
+ 838 +
+
+ 1 +
+
+

+            
+
+
+ 839 +
+
+ 1 +
+
+
    // Create variables and domains
+
+
+
+ 840 +
+
+ 1 +
+
+
    let variable_a = Name::UserName(String::from("a"));
+
+
+
+ 841 +
+
+ 1 +
+
+
    let variable_b = Name::UserName(String::from("b"));
+
+
+
+ 842 +
+
+ 1 +
+
+
    let variable_c = Name::UserName(String::from("c"));
+
+
+
+ 843 +
+
+ 1 +
+
+
    let domain = Domain::IntDomain(vec![Range::Bounded(1, 3)]);
+
+
+
+ 844 +
+
+ 1 +
+
+

+            
+
+
+ 845 +
+
+ 1 +
+
+
    // Construct nested expression
+
+
+
+ 846 +
+
+ 1 +
+
+
    let nested_expr = Expression::And(
+
+
+
+ 847 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 848 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 849 +
+
+ 1 +
+
+
            Expression::Eq(
+
+
+
+ 850 +
+
+ 1 +
+
+
                Metadata::new(),
+
+
+
+ 851 +
+
+ 1 +
+
+
                Box::new(Expression::Sum(
+
+
+
+ 852 +
+
+ 1 +
+
+
                    Metadata::new(),
+
+
+
+ 853 +
+
+ 1 +
+
+
                    vec![
+
+
+
+ 854 +
+
+ 1 +
+
+
                        Expression::Reference(Metadata::new(), variable_a.clone()),
+
+
+
+ 855 +
+
+ 1 +
+
+
                        Expression::Reference(Metadata::new(), variable_b.clone()),
+
+
+
+ 856 +
+
+ 1 +
+
+
                        Expression::Reference(Metadata::new(), variable_c.clone()),
+
+
+
+ 857 +
+
+ 1 +
+
+
                    ],
+
+
+
+ 858 +
+
+ 1 +
+
+
                )),
+
+
+
+ 859 +
+
+ 1 +
+
+
                Box::new(Expression::Constant(Metadata::new(), Constant::Int(4))),
+
+
+
+ 860 +
+
+ 1 +
+
+
            ),
+
+
+
+ 861 +
+
+ 1 +
+
+
            Expression::Lt(
+
+
+
+ 862 +
+
+ 1 +
+
+
                Metadata::new(),
+
+
+
+ 863 +
+
+ 1 +
+
+
                Box::new(Expression::Reference(Metadata::new(), variable_a.clone())),
+
+
+
+ 864 +
+
+ 1 +
+
+
                Box::new(Expression::Reference(Metadata::new(), variable_b.clone())),
+
+
+
+ 865 +
+
+ 1 +
+
+
            ),
+
+
+
+ 866 +
+
+ 1 +
+
+
        ],
+
+
+
+ 867 +
+
+ 1 +
+
+
    );
+
+
+
+ 868 +
+
+ +
+
+

+            
+
+
+ 869 +
+
+ 1 +
+
+
    let rule_sets = match resolve_rule_sets(SolverFamily::Minion, &vec!["Constant"]) {
+
+
+
+ 870 +
+
+ 1 +
+
+
        Ok(rs) => rs,
+
+
+
+ 871 +
+
+ +
+
+
        Err(e) => {
+
+
+
+ 872 +
+
+ +
+
+
            eprintln!("Error resolving rule sets: {}", e);
+
+
+
+ 873 +
+
+ +
+
+
            exit(1);
+
+
+
+ 874 +
+
+ +
+
+
        }
+
+
+
+ 875 +
+
+ +
+
+
    };
+
+
+
+ 876 +
+
+ +
+
+

+            
+
+
+ 877 +
+
+ +
+
+
    // Apply rewrite function to the nested expression
+
+
+
+ 878 +
+
+ 1 +
+
+
    let rewritten_expr = rewrite_model(
+
+
+
+ 879 +
+
+ 1 +
+
+
        &Model::new(HashMap::new(), nested_expr, Default::default()),
+
+
+
+ 880 +
+
+ 1 +
+
+
        &rule_sets,
+
+
+
+ 881 +
+
+ 1 +
+
+
    )
+
+
+
+ 882 +
+
+ 1 +
+
+
    .unwrap()
+
+
+
+ 883 +
+
+ 1 +
+
+
    .constraints;
+
+
+
+ 884 +
+
+ 1 +
+
+

+            
+
+
+ 885 +
+
+ 1 +
+
+
    // Check if the expression is in its simplest form
+
+
+
+ 886 +
+
+ 1 +
+
+
    let expr = rewritten_expr.clone();
+
+
+
+ 887 +
+
+ 1 +
+
+
    assert!(is_simple(&expr));
+
+
+
+ 888 +
+
+ +
+
+

+            
+
+
+ 889 +
+
+ +
+
+
    // Create model with variables and constraints
+
+
+
+ 890 +
+
+ 1 +
+
+
    let mut model = Model::new(HashMap::new(), rewritten_expr, Default::default());
+
+
+
+ 891 +
+
+ 1 +
+
+

+            
+
+
+ 892 +
+
+ 1 +
+
+
    // Insert variables and domains
+
+
+
+ 893 +
+
+ 1 +
+
+
    model.variables.insert(
+
+
+
+ 894 +
+
+ 1 +
+
+
        variable_a.clone(),
+
+
+
+ 895 +
+
+ 1 +
+
+
        DecisionVariable {
+
+
+
+ 896 +
+
+ 1 +
+
+
            domain: domain.clone(),
+
+
+
+ 897 +
+
+ 1 +
+
+
        },
+
+
+
+ 898 +
+
+ 1 +
+
+
    );
+
+
+
+ 899 +
+
+ 1 +
+
+
    model.variables.insert(
+
+
+
+ 900 +
+
+ 1 +
+
+
        variable_b.clone(),
+
+
+
+ 901 +
+
+ 1 +
+
+
        DecisionVariable {
+
+
+
+ 902 +
+
+ 1 +
+
+
            domain: domain.clone(),
+
+
+
+ 903 +
+
+ 1 +
+
+
        },
+
+
+
+ 904 +
+
+ 1 +
+
+
    );
+
+
+
+ 905 +
+
+ 1 +
+
+
    model.variables.insert(
+
+
+
+ 906 +
+
+ 1 +
+
+
        variable_c.clone(),
+
+
+
+ 907 +
+
+ 1 +
+
+
        DecisionVariable {
+
+
+
+ 908 +
+
+ 1 +
+
+
            domain: domain.clone(),
+
+
+
+ 909 +
+
+ 1 +
+
+
        },
+
+
+
+ 910 +
+
+ 1 +
+
+
    );
+
+
+
+ 911 +
+
+ 1 +
+
+

+            
+
+
+ 912 +
+
+ 1 +
+
+
    let solver: Solver<adaptors::Minion> = Solver::new(adaptors::Minion::new());
+
+
+
+ 913 +
+
+ 1 +
+
+
    let solver = solver.load_model(model).unwrap();
+
+
+
+ 914 +
+
+ 1 +
+
+
    solver.solve(Box::new(|_| true)).unwrap();
+
+
+
+ 915 +
+
+ 1 +
+
+
}
+
+
+
+ 916 +
+
+ +
+
+

+            
+
+
+ 917 +
+
+ +
+
+
struct RuleResult<'a> {
+
+
+
+ 918 +
+
+ +
+
+
    #[allow(dead_code)]
+
+
+
+ 919 +
+
+ +
+
+
    rule: &'a Rule<'a>,
+
+
+
+ 920 +
+
+ +
+
+
    new_expression: Expression,
+
+
+
+ 921 +
+
+ +
+
+
}
+
+
+
+ 922 +
+
+ +
+
+

+            
+
+
+ 923 +
+
+ +
+
+
/// # Returns
+
+
+
+ 924 +
+
+ +
+
+
/// - True if `expression` is in its simplest form.
+
+
+
+ 925 +
+
+ +
+
+
/// - False otherwise.
+
+
+
+ 926 +
+
+ 1 +
+
+
pub fn is_simple(expression: &Expression) -> bool {
+
+
+
+ 927 +
+
+ 1 +
+
+
    let rules = get_rules();
+
+
+
+ 928 +
+
+ 1 +
+
+
    let mut new = expression.clone();
+
+
+
+ 929 +
+
+ 1 +
+
+
    while let Some(step) = is_simple_iteration(&new, &rules) {
+
+
+
+ 930 +
+
+ +
+
+
        new = step;
+
+
+
+ 931 +
+
+ +
+
+
    }
+
+
+
+ 932 +
+
+ 1 +
+
+
    new == *expression
+
+
+
+ 933 +
+
+ 1 +
+
+
}
+
+
+
+ 934 +
+
+ +
+
+

+            
+
+
+ 935 +
+
+ +
+
+
/// # Returns
+
+
+
+ 936 +
+
+ +
+
+
/// - Some(<new_expression>) after applying the first applicable rule to `expr` or a sub-expression.
+
+
+
+ 937 +
+
+ +
+
+
/// - None if no rule is applicable to the expression or any sub-expression.
+
+
+
+ 938 +
+
+ 15 +
+
+
fn is_simple_iteration<'a>(
+
+
+
+ 939 +
+
+ 15 +
+
+
    expression: &'a Expression,
+
+
+
+ 940 +
+
+ 15 +
+
+
    rules: &'a Vec<&'a Rule<'a>>,
+
+
+
+ 941 +
+
+ 15 +
+
+
) -> Option<Expression> {
+
+
+
+ 942 +
+
+ 15 +
+
+
    let rule_results = apply_all_rules(expression, rules);
+
+
+
+ 943 +
+
+ 15 +
+
+
    if let Some(new) = choose_rewrite(&rule_results) {
+
+
+
+ 944 +
+
+ +
+
+
        return Some(new);
+
+
+
+ 945 +
+
+ +
+
+
    } else {
+
+
+
+ 946 +
+
+ 15 +
+
+
        let mut sub = expression.children();
+
+
+
+ 947 +
+
+ 15 +
+
+
        for i in 0..sub.len() {
+
+
+
+ 948 +
+
+ 14 +
+
+
            if let Some(new) = is_simple_iteration(&sub[i], rules) {
+
+
+
+ 949 +
+
+ +
+
+
                sub[i] = new;
+
+
+
+ 950 +
+
+ +
+
+
                if let Ok(res) = expression.with_children(sub.clone()) {
+
+
+
+ 951 +
+
+ +
+
+
                    return Some(res);
+
+
+
+ 952 +
+
+ +
+
+
                }
+
+
+
+ 953 +
+
+ 14 +
+
+
            }
+
+
+
+ 954 +
+
+ +
+
+
        }
+
+
+
+ 955 +
+
+ +
+
+
    }
+
+
+
+ 956 +
+
+ 15 +
+
+
    None // No rules applicable to this branch of the expression
+
+
+
+ 957 +
+
+ 15 +
+
+
}
+
+
+
+ 958 +
+
+ +
+
+

+            
+
+
+ 959 +
+
+ +
+
+
/// # Returns
+
+
+
+ 960 +
+
+ +
+
+
/// - A list of RuleResults after applying all rules to `expression`.
+
+
+
+ 961 +
+
+ +
+
+
/// - An empty list if no rules are applicable.
+
+
+
+ 962 +
+
+ 15 +
+
+
fn apply_all_rules<'a>(
+
+
+
+ 963 +
+
+ 15 +
+
+
    expression: &'a Expression,
+
+
+
+ 964 +
+
+ 15 +
+
+
    rules: &'a Vec<&'a Rule<'a>>,
+
+
+
+ 965 +
+
+ 15 +
+
+
) -> Vec<RuleResult<'a>> {
+
+
+
+ 966 +
+
+ 15 +
+
+
    let mut results = Vec::new();
+
+
+
+ 967 +
+
+ 435 +
+
+
    for rule in rules {
+
+
+
+ 968 +
+
+ 420 +
+
+
        match rule.apply(expression, &Model::new_empty(Default::default())) {
+
+
+
+ 969 +
+
+ +
+
+
            Ok(red) => {
+
+
+
+ 970 +
+
+ +
+
+
                results.push(RuleResult {
+
+
+
+ 971 +
+
+ +
+
+
                    rule,
+
+
+
+ 972 +
+
+ +
+
+
                    new_expression: red.new_expression,
+
+
+
+ 973 +
+
+ +
+
+
                });
+
+
+
+ 974 +
+
+ +
+
+
            }
+
+
+
+ 975 +
+
+ 420 +
+
+
            Err(_) => continue,
+
+
+
+ 976 +
+
+ +
+
+
        }
+
+
+
+ 977 +
+
+ +
+
+
    }
+
+
+
+ 978 +
+
+ 15 +
+
+
    results
+
+
+
+ 979 +
+
+ 15 +
+
+
}
+
+
+
+ 980 +
+
+ +
+
+

+            
+
+
+ 981 +
+
+ +
+
+
/// # Returns
+
+
+
+ 982 +
+
+ +
+
+
/// - Some(<new_expression>) after applying the first rule in `results`.
+
+
+
+ 983 +
+
+ +
+
+
/// - None if `results` is empty.
+
+
+
+ 984 +
+
+ 15 +
+
+
fn choose_rewrite(results: &[RuleResult]) -> Option<Expression> {
+
+
+
+ 985 +
+
+ 15 +
+
+
    if results.is_empty() {
+
+
+
+ 986 +
+
+ 15 +
+
+
        return None;
+
+
+
+ 987 +
+
+ +
+
+
    }
+
+
+
+ 988 +
+
+ +
+
+
    // Return the first result for now
+
+
+
+ 989 +
+
+ +
+
+
    // println!("Applying rule: {:?}", results[0].rule);
+
+
+
+ 990 +
+
+ +
+
+
    Some(results[0].new_expression.clone())
+
+
+
+ 991 +
+
+ 15 +
+
+
}
+
+
+
+ 992 +
+
+ +
+
+

+            
+
+
+ 993 +
+
+ +
+
+
#[test]
+
+
+
+ 994 +
+
+ 1 +
+
+
fn eval_const_int() {
+
+
+
+ 995 +
+
+ 1 +
+
+
    let expr = Expression::Constant(Metadata::new(), Constant::Int(1));
+
+
+
+ 996 +
+
+ 1 +
+
+
    let result = eval_constant(&expr);
+
+
+
+ 997 +
+
+ 1 +
+
+
    assert_eq!(result, Some(Constant::Int(1)));
+
+
+
+ 998 +
+
+ 1 +
+
+
}
+
+
+
+ 999 +
+
+ +
+
+

+            
+
+
+ 1000 +
+
+ +
+
+
#[test]
+
+
+
+ 1001 +
+
+ 1 +
+
+
fn eval_const_bool() {
+
+
+
+ 1002 +
+
+ 1 +
+
+
    let expr = Expression::Constant(Metadata::new(), Constant::Bool(true));
+
+
+
+ 1003 +
+
+ 1 +
+
+
    let result = eval_constant(&expr);
+
+
+
+ 1004 +
+
+ 1 +
+
+
    assert_eq!(result, Some(Constant::Bool(true)));
+
+
+
+ 1005 +
+
+ 1 +
+
+
}
+
+
+
+ 1006 +
+
+ +
+
+

+            
+
+
+ 1007 +
+
+ +
+
+
#[test]
+
+
+
+ 1008 +
+
+ 1 +
+
+
fn eval_const_and() {
+
+
+
+ 1009 +
+
+ 1 +
+
+
    let expr = Expression::And(
+
+
+
+ 1010 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 1011 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 1012 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Bool(true)),
+
+
+
+ 1013 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Bool(false)),
+
+
+
+ 1014 +
+
+ 1 +
+
+
        ],
+
+
+
+ 1015 +
+
+ 1 +
+
+
    );
+
+
+
+ 1016 +
+
+ 1 +
+
+
    let result = eval_constant(&expr);
+
+
+
+ 1017 +
+
+ 1 +
+
+
    assert_eq!(result, Some(Constant::Bool(false)));
+
+
+
+ 1018 +
+
+ 1 +
+
+
}
+
+
+
+ 1019 +
+
+ +
+
+

+            
+
+
+ 1020 +
+
+ +
+
+
#[test]
+
+
+
+ 1021 +
+
+ 1 +
+
+
fn eval_const_ref() {
+
+
+
+ 1022 +
+
+ 1 +
+
+
    let expr = Expression::Reference(Metadata::new(), Name::UserName(String::from("a")));
+
+
+
+ 1023 +
+
+ 1 +
+
+
    let result = eval_constant(&expr);
+
+
+
+ 1024 +
+
+ 1 +
+
+
    assert_eq!(result, None);
+
+
+
+ 1025 +
+
+ 1 +
+
+
}
+
+
+
+ 1026 +
+
+ +
+
+

+            
+
+
+ 1027 +
+
+ +
+
+
#[test]
+
+
+
+ 1028 +
+
+ 1 +
+
+
fn eval_const_nested_ref() {
+
+
+
+ 1029 +
+
+ 1 +
+
+
    let expr = Expression::Sum(
+
+
+
+ 1030 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 1031 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 1032 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Int(1)),
+
+
+
+ 1033 +
+
+ 1 +
+
+
            Expression::And(
+
+
+
+ 1034 +
+
+ 1 +
+
+
                Metadata::new(),
+
+
+
+ 1035 +
+
+ 1 +
+
+
                vec![
+
+
+
+ 1036 +
+
+ 1 +
+
+
                    Expression::Constant(Metadata::new(), Constant::Bool(true)),
+
+
+
+ 1037 +
+
+ 1 +
+
+
                    Expression::Reference(Metadata::new(), Name::UserName(String::from("a"))),
+
+
+
+ 1038 +
+
+ 1 +
+
+
                ],
+
+
+
+ 1039 +
+
+ 1 +
+
+
            ),
+
+
+
+ 1040 +
+
+ 1 +
+
+
        ],
+
+
+
+ 1041 +
+
+ 1 +
+
+
    );
+
+
+
+ 1042 +
+
+ 1 +
+
+
    let result = eval_constant(&expr);
+
+
+
+ 1043 +
+
+ 1 +
+
+
    assert_eq!(result, None);
+
+
+
+ 1044 +
+
+ 1 +
+
+
}
+
+
+
+ 1045 +
+
+ +
+
+

+            
+
+
+ 1046 +
+
+ +
+
+
#[test]
+
+
+
+ 1047 +
+
+ 1 +
+
+
fn eval_const_eq_int() {
+
+
+
+ 1048 +
+
+ 1 +
+
+
    let expr = Expression::Eq(
+
+
+
+ 1049 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 1050 +
+
+ 1 +
+
+
        Box::new(Expression::Constant(Metadata::new(), Constant::Int(1))),
+
+
+
+ 1051 +
+
+ 1 +
+
+
        Box::new(Expression::Constant(Metadata::new(), Constant::Int(1))),
+
+
+
+ 1052 +
+
+ 1 +
+
+
    );
+
+
+
+ 1053 +
+
+ 1 +
+
+
    let result = eval_constant(&expr);
+
+
+
+ 1054 +
+
+ 1 +
+
+
    assert_eq!(result, Some(Constant::Bool(true)));
+
+
+
+ 1055 +
+
+ 1 +
+
+
}
+
+
+
+ 1056 +
+
+ +
+
+

+            
+
+
+ 1057 +
+
+ +
+
+
#[test]
+
+
+
+ 1058 +
+
+ 1 +
+
+
fn eval_const_eq_bool() {
+
+
+
+ 1059 +
+
+ 1 +
+
+
    let expr = Expression::Eq(
+
+
+
+ 1060 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 1061 +
+
+ 1 +
+
+
        Box::new(Expression::Constant(Metadata::new(), Constant::Bool(true))),
+
+
+
+ 1062 +
+
+ 1 +
+
+
        Box::new(Expression::Constant(Metadata::new(), Constant::Bool(true))),
+
+
+
+ 1063 +
+
+ 1 +
+
+
    );
+
+
+
+ 1064 +
+
+ 1 +
+
+
    let result = eval_constant(&expr);
+
+
+
+ 1065 +
+
+ 1 +
+
+
    assert_eq!(result, Some(Constant::Bool(true)));
+
+
+
+ 1066 +
+
+ 1 +
+
+
}
+
+
+
+ 1067 +
+
+ +
+
+

+            
+
+
+ 1068 +
+
+ +
+
+
#[test]
+
+
+
+ 1069 +
+
+ 1 +
+
+
fn eval_const_eq_mixed() {
+
+
+
+ 1070 +
+
+ 1 +
+
+
    let expr = Expression::Eq(
+
+
+
+ 1071 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 1072 +
+
+ 1 +
+
+
        Box::new(Expression::Constant(Metadata::new(), Constant::Int(1))),
+
+
+
+ 1073 +
+
+ 1 +
+
+
        Box::new(Expression::Constant(Metadata::new(), Constant::Bool(true))),
+
+
+
+ 1074 +
+
+ 1 +
+
+
    );
+
+
+
+ 1075 +
+
+ 1 +
+
+
    let result = eval_constant(&expr);
+
+
+
+ 1076 +
+
+ 1 +
+
+
    assert_eq!(result, None);
+
+
+
+ 1077 +
+
+ 1 +
+
+
}
+
+
+
+ 1078 +
+
+ +
+
+

+            
+
+
+ 1079 +
+
+ +
+
+
#[test]
+
+
+
+ 1080 +
+
+ 1 +
+
+
fn eval_const_sum_mixed() {
+
+
+
+ 1081 +
+
+ 1 +
+
+
    let expr = Expression::Sum(
+
+
+
+ 1082 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 1083 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 1084 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Int(1)),
+
+
+
+ 1085 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Bool(true)),
+
+
+
+ 1086 +
+
+ 1 +
+
+
        ],
+
+
+
+ 1087 +
+
+ 1 +
+
+
    );
+
+
+
+ 1088 +
+
+ 1 +
+
+
    let result = eval_constant(&expr);
+
+
+
+ 1089 +
+
+ 1 +
+
+
    assert_eq!(result, None);
+
+
+
+ 1090 +
+
+ 1 +
+
+
}
+
+
+
+ 1091 +
+
+ +
+
+

+            
+
+
+ 1092 +
+
+ +
+
+
#[test]
+
+
+
+ 1093 +
+
+ 1 +
+
+
fn eval_const_sum_xyz() {
+
+
+
+ 1094 +
+
+ 1 +
+
+
    let expr = Expression::And(
+
+
+
+ 1095 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 1096 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 1097 +
+
+ 1 +
+
+
            Expression::Eq(
+
+
+
+ 1098 +
+
+ 1 +
+
+
                Metadata::new(),
+
+
+
+ 1099 +
+
+ 1 +
+
+
                Box::new(Expression::Sum(
+
+
+
+ 1100 +
+
+ 1 +
+
+
                    Metadata::new(),
+
+
+
+ 1101 +
+
+ 1 +
+
+
                    vec![
+
+
+
+ 1102 +
+
+ 1 +
+
+
                        Expression::Reference(Metadata::new(), Name::UserName(String::from("x"))),
+
+
+
+ 1103 +
+
+ 1 +
+
+
                        Expression::Reference(Metadata::new(), Name::UserName(String::from("y"))),
+
+
+
+ 1104 +
+
+ 1 +
+
+
                        Expression::Reference(Metadata::new(), Name::UserName(String::from("z"))),
+
+
+
+ 1105 +
+
+ 1 +
+
+
                    ],
+
+
+
+ 1106 +
+
+ 1 +
+
+
                )),
+
+
+
+ 1107 +
+
+ 1 +
+
+
                Box::new(Expression::Constant(Metadata::new(), Constant::Int(4))),
+
+
+
+ 1108 +
+
+ 1 +
+
+
            ),
+
+
+
+ 1109 +
+
+ 1 +
+
+
            Expression::Geq(
+
+
+
+ 1110 +
+
+ 1 +
+
+
                Metadata::new(),
+
+
+
+ 1111 +
+
+ 1 +
+
+
                Box::new(Expression::Reference(
+
+
+
+ 1112 +
+
+ 1 +
+
+
                    Metadata::new(),
+
+
+
+ 1113 +
+
+ 1 +
+
+
                    Name::UserName(String::from("x")),
+
+
+
+ 1114 +
+
+ 1 +
+
+
                )),
+
+
+
+ 1115 +
+
+ 1 +
+
+
                Box::new(Expression::Reference(
+
+
+
+ 1116 +
+
+ 1 +
+
+
                    Metadata::new(),
+
+
+
+ 1117 +
+
+ 1 +
+
+
                    Name::UserName(String::from("y")),
+
+
+
+ 1118 +
+
+ 1 +
+
+
                )),
+
+
+
+ 1119 +
+
+ 1 +
+
+
            ),
+
+
+
+ 1120 +
+
+ 1 +
+
+
        ],
+
+
+
+ 1121 +
+
+ 1 +
+
+
    );
+
+
+
+ 1122 +
+
+ 1 +
+
+
    let result = eval_constant(&expr);
+
+
+
+ 1123 +
+
+ 1 +
+
+
    assert_eq!(result, None);
+
+
+
+ 1124 +
+
+ 1 +
+
+
}
+
+
+
+ 1125 +
+
+ +
+
+

+            
+
+
+ 1126 +
+
+ +
+
+
#[test]
+
+
+
+ 1127 +
+
+ 1 +
+
+
fn eval_const_or() {
+
+
+
+ 1128 +
+
+ 1 +
+
+
    let expr = Expression::Or(
+
+
+
+ 1129 +
+
+ 1 +
+
+
        Metadata::new(),
+
+
+
+ 1130 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 1131 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Bool(false)),
+
+
+
+ 1132 +
+
+ 1 +
+
+
            Expression::Constant(Metadata::new(), Constant::Bool(false)),
+
+
+
+ 1133 +
+
+ 1 +
+
+
        ],
+
+
+
+ 1134 +
+
+ 1 +
+
+
    );
+
+
+
+ 1135 +
+
+ 1 +
+
+
    let result = eval_constant(&expr);
+
+
+
+ 1136 +
+
+ 1 +
+
+
    assert_eq!(result, Some(Constant::Bool(false)));
+
+
+
+ 1137 +
+
+ 1 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/coverage.json b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/coverage.json new file mode 100644 index 0000000000..fa01bb48c4 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/coverage.json @@ -0,0 +1 @@ +{"schemaVersion":1,"label":"coverage","message":"73.18%","color":"red"} \ No newline at end of file diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/constants.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/constants.rs.html new file mode 100644 index 0000000000..6b6d45db6f --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/constants.rs.html @@ -0,0 +1,665 @@ + + + + + Grcov report - constants.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use std::fmt::{Display, Formatter};
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
use serde::{Deserialize, Serialize};
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ 690 +
+
+
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+
+
+
+ 6 +
+
+ +
+
+
pub enum Constant {
+
+
+
+ 7 +
+
+ +
+
+
    Int(i32),
+
+
+
+ 8 +
+
+ +
+
+
    Bool(bool),
+
+
+
+ 9 +
+
+ +
+
+
}
+
+
+
+ 10 +
+
+ +
+
+

+            
+
+
+ 11 +
+
+ +
+
+
impl TryFrom<Constant> for i32 {
+
+
+
+ 12 +
+
+ +
+
+
    type Error = &'static str;
+
+
+
+ 13 +
+
+ +
+
+

+            
+
+
+ 14 +
+
+ 1110 +
+
+
    fn try_from(value: Constant) -> Result<Self, Self::Error> {
+
+
+
+ 15 +
+
+ 1110 +
+
+
        match value {
+
+
+
+ 16 +
+
+ 1065 +
+
+
            Constant::Int(i) => Ok(i),
+
+
+
+ 17 +
+
+ 45 +
+
+
            _ => Err("Cannot convert non-i32 Constant to i32"),
+
+
+
+ 18 +
+
+ +
+
+
        }
+
+
+
+ 19 +
+
+ 1110 +
+
+
    }
+
+
+
+ 20 +
+
+ +
+
+
}
+
+
+
+ 21 +
+
+ +
+
+
impl TryFrom<Constant> for bool {
+
+
+
+ 22 +
+
+ +
+
+
    type Error = &'static str;
+
+
+
+ 23 +
+
+ +
+
+

+            
+
+
+ 24 +
+
+ 120 +
+
+
    fn try_from(value: Constant) -> Result<Self, Self::Error> {
+
+
+
+ 25 +
+
+ 120 +
+
+
        match value {
+
+
+
+ 26 +
+
+ 105 +
+
+
            Constant::Bool(b) => Ok(b),
+
+
+
+ 27 +
+
+ 15 +
+
+
            _ => Err("Cannot convert non-bool Constant to bool"),
+
+
+
+ 28 +
+
+ +
+
+
        }
+
+
+
+ 29 +
+
+ 120 +
+
+
    }
+
+
+
+ 30 +
+
+ +
+
+
}
+
+
+
+ 31 +
+
+ +
+
+

+            
+
+
+ 32 +
+
+ +
+
+
impl Display for Constant {
+
+
+
+ 33 +
+
+ +
+
+
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+
+
+
+ 34 +
+
+ +
+
+
        match &self {
+
+
+
+ 35 +
+
+ +
+
+
            Constant::Int(i) => write!(f, "Int({})", i),
+
+
+
+ 36 +
+
+ +
+
+
            Constant::Bool(b) => write!(f, "Bool({})", b),
+
+
+
+ 37 +
+
+ +
+
+
        }
+
+
+
+ 38 +
+
+ +
+
+
    }
+
+
+
+ 39 +
+
+ +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/domains.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/domains.rs.html new file mode 100644 index 0000000000..5827d943a5 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/domains.rs.html @@ -0,0 +1,1353 @@ + + + + + Grcov report - domains.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use serde::{Deserialize, Serialize};
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ 465 +
+
+
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+
+
+
+ 4 +
+
+ +
+
+
pub enum Range<A> {
+
+
+
+ 5 +
+
+ +
+
+
    Single(A),
+
+
+
+ 6 +
+
+ +
+
+
    Bounded(A, A),
+
+
+
+ 7 +
+
+ +
+
+
}
+
+
+
+ 8 +
+
+ +
+
+

+            
+
+
+ 9 +
+
+ 410 +
+
+
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+
+
+
+ 10 +
+
+ +
+
+
pub enum Domain {
+
+
+
+ 11 +
+
+ +
+
+
    BoolDomain,
+
+
+
+ 12 +
+
+ +
+
+
    IntDomain(Vec<Range<i32>>),
+
+
+
+ 13 +
+
+ +
+
+
}
+
+
+
+ 14 +
+
+ +
+
+

+            
+
+
+ 15 +
+
+ +
+
+
impl Domain {
+
+
+
+ 16 +
+
+ +
+
+
    /// Returns the minimum i32 value a variable of the domain can take, if it is an i32 domain.
+
+
+
+ 17 +
+
+ +
+
+
    pub fn min_i32(&self) -> Option<i32> {
+
+
+
+ 18 +
+
+ +
+
+
        match self {
+
+
+
+ 19 +
+
+ +
+
+
            Domain::BoolDomain => Some(0),
+
+
+
+ 20 +
+
+ +
+
+
            Domain::IntDomain(ranges) => {
+
+
+
+ 21 +
+
+ +
+
+
                if ranges.is_empty() {
+
+
+
+ 22 +
+
+ +
+
+
                    return None;
+
+
+
+ 23 +
+
+ +
+
+
                }
+
+
+
+ 24 +
+
+ +
+
+
                let mut min = i32::MAX;
+
+
+
+ 25 +
+
+ +
+
+
                for r in ranges {
+
+
+
+ 26 +
+
+ +
+
+
                    match r {
+
+
+
+ 27 +
+
+ +
+
+
                        Range::Single(i) => min = min.min(*i),
+
+
+
+ 28 +
+
+ +
+
+
                        Range::Bounded(i, _) => min = min.min(*i),
+
+
+
+ 29 +
+
+ +
+
+
                    }
+
+
+
+ 30 +
+
+ +
+
+
                }
+
+
+
+ 31 +
+
+ +
+
+
                Some(min)
+
+
+
+ 32 +
+
+ +
+
+
            }
+
+
+
+ 33 +
+
+ +
+
+
        }
+
+
+
+ 34 +
+
+ +
+
+
    }
+
+
+
+ 35 +
+
+ +
+
+

+            
+
+
+ 36 +
+
+ +
+
+
    /// Returns the maximum i32 value a variable of the domain can take, if it is an i32 domain.
+
+
+
+ 37 +
+
+ +
+
+
    pub fn max_i32(&self) -> Option<i32> {
+
+
+
+ 38 +
+
+ +
+
+
        match self {
+
+
+
+ 39 +
+
+ +
+
+
            Domain::BoolDomain => Some(1),
+
+
+
+ 40 +
+
+ +
+
+
            Domain::IntDomain(ranges) => {
+
+
+
+ 41 +
+
+ +
+
+
                if ranges.is_empty() {
+
+
+
+ 42 +
+
+ +
+
+
                    return None;
+
+
+
+ 43 +
+
+ +
+
+
                }
+
+
+
+ 44 +
+
+ +
+
+
                let mut max = i32::MIN;
+
+
+
+ 45 +
+
+ +
+
+
                for r in ranges {
+
+
+
+ 46 +
+
+ +
+
+
                    match r {
+
+
+
+ 47 +
+
+ +
+
+
                        Range::Single(i) => max = max.max(*i),
+
+
+
+ 48 +
+
+ +
+
+
                        Range::Bounded(_, i) => max = max.max(*i),
+
+
+
+ 49 +
+
+ +
+
+
                    }
+
+
+
+ 50 +
+
+ +
+
+
                }
+
+
+
+ 51 +
+
+ +
+
+
                Some(max)
+
+
+
+ 52 +
+
+ +
+
+
            }
+
+
+
+ 53 +
+
+ +
+
+
        }
+
+
+
+ 54 +
+
+ +
+
+
    }
+
+
+
+ 55 +
+
+ +
+
+

+            
+
+
+ 56 +
+
+ +
+
+
    /// Returns the minimum and maximum integer values a variable of the domain can take, if it is an integer domain.
+
+
+
+ 57 +
+
+ 150 +
+
+
    pub fn min_max_i32(&self) -> Option<(i32, i32)> {
+
+
+
+ 58 +
+
+ 150 +
+
+
        match self {
+
+
+
+ 59 +
+
+ +
+
+
            Domain::BoolDomain => Some((0, 1)),
+
+
+
+ 60 +
+
+ 150 +
+
+
            Domain::IntDomain(ranges) => {
+
+
+
+ 61 +
+
+ 150 +
+
+
                if ranges.is_empty() {
+
+
+
+ 62 +
+
+ +
+
+
                    return None;
+
+
+
+ 63 +
+
+ 150 +
+
+
                }
+
+
+
+ 64 +
+
+ 150 +
+
+
                let mut min = i32::MAX;
+
+
+
+ 65 +
+
+ 150 +
+
+
                let mut max = i32::MIN;
+
+
+
+ 66 +
+
+ 300 +
+
+
                for r in ranges {
+
+
+
+ 67 +
+
+ 150 +
+
+
                    match r {
+
+
+
+ 68 +
+
+ +
+
+
                        Range::Single(i) => {
+
+
+
+ 69 +
+
+ +
+
+
                            min = min.min(*i);
+
+
+
+ 70 +
+
+ +
+
+
                            max = max.max(*i);
+
+
+
+ 71 +
+
+ +
+
+
                        }
+
+
+
+ 72 +
+
+ 150 +
+
+
                        Range::Bounded(i, j) => {
+
+
+
+ 73 +
+
+ 150 +
+
+
                            min = min.min(*i);
+
+
+
+ 74 +
+
+ 150 +
+
+
                            max = max.max(*j);
+
+
+
+ 75 +
+
+ 150 +
+
+
                        }
+
+
+
+ 76 +
+
+ +
+
+
                    }
+
+
+
+ 77 +
+
+ +
+
+
                }
+
+
+
+ 78 +
+
+ 150 +
+
+
                Some((min, max))
+
+
+
+ 79 +
+
+ +
+
+
            }
+
+
+
+ 80 +
+
+ +
+
+
        }
+
+
+
+ 81 +
+
+ 150 +
+
+
    }
+
+
+
+ 82 +
+
+ +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/expressions.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/expressions.rs.html new file mode 100644 index 0000000000..1ee2c1fef1 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/expressions.rs.html @@ -0,0 +1,3513 @@ + + + + + Grcov report - expressions.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use std::fmt::{Display, Formatter};
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
use derive_is_enum_variant::is_enum_variant;
+
+
+
+ 4 +
+
+ +
+
+
use serde::{Deserialize, Serialize};
+
+
+
+ 5 +
+
+ +
+
+

+            
+
+
+ 6 +
+
+ +
+
+
use enum_compatability_macro::document_compatibility;
+
+
+
+ 7 +
+
+ +
+
+
use uniplate::uniplate::Uniplate;
+
+
+
+ 8 +
+
+ +
+
+
use uniplate_derive::Uniplate;
+
+
+
+ 9 +
+
+ +
+
+

+            
+
+
+ 10 +
+
+ +
+
+
use crate::ast::constants::Constant;
+
+
+
+ 11 +
+
+ +
+
+
use crate::ast::symbol_table::{Name, SymbolTable};
+
+
+
+ 12 +
+
+ +
+
+
use crate::metadata::Metadata;
+
+
+
+ 13 +
+
+ +
+
+

+            
+
+
+ 14 +
+
+ +
+
+
#[document_compatibility]
+
+
+
+ 15 +
+
+ 73920 +
+
+
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, is_enum_variant, Uniplate)]
+
+
+
+ 16 +
+
+ +
+
+
#[non_exhaustive]
+
+
+
+ 17 +
+
+ +
+
+
pub enum Expression {
+
+
+
+ 18 +
+
+ +
+
+
    /**
+
+
+
+ 19 +
+
+ +
+
+
     * Represents an empty expression
+
+
+
+ 20 +
+
+ +
+
+
     * NB: we only expect this at the top level of a model (if there is no constraints)
+
+
+
+ 21 +
+
+ +
+
+
     */
+
+
+
+ 22 +
+
+ +
+
+
    Nothing,
+
+
+
+ 23 +
+
+ +
+
+

+            
+
+
+ 24 +
+
+ +
+
+
    #[compatible(Minion, JsonInput)]
+
+
+
+ 25 +
+
+ +
+
+
    Constant(Metadata, Constant),
+
+
+
+ 26 +
+
+ +
+
+

+            
+
+
+ 27 +
+
+ +
+
+
    #[compatible(Minion, JsonInput, SAT)]
+
+
+
+ 28 +
+
+ +
+
+
    Reference(Metadata, Name),
+
+
+
+ 29 +
+
+ +
+
+

+            
+
+
+ 30 +
+
+ +
+
+
    #[compatible(Minion, JsonInput)]
+
+
+
+ 31 +
+
+ +
+
+
    Sum(Metadata, Vec<Expression>),
+
+
+
+ 32 +
+
+ +
+
+

+            
+
+
+ 33 +
+
+ +
+
+
    // /// Division after preventing division by zero, usually with a top-level constraint
+
+
+
+ 34 +
+
+ +
+
+
    // #[compatible(Minion)]
+
+
+
+ 35 +
+
+ +
+
+
    // SafeDiv(Metadata, Box<Expression>, Box<Expression>),
+
+
+
+ 36 +
+
+ +
+
+
    // /// Division with a possibly undefined value (division by 0)
+
+
+
+ 37 +
+
+ +
+
+
    // #[compatible(Minion, JsonInput)]
+
+
+
+ 38 +
+
+ +
+
+
    // Div(Metadata, Box<Expression>, Box<Expression>),
+
+
+
+ 39 +
+
+ +
+
+
    #[compatible(JsonInput)]
+
+
+
+ 40 +
+
+ +
+
+
    Min(Metadata, Vec<Expression>),
+
+
+
+ 41 +
+
+ +
+
+

+            
+
+
+ 42 +
+
+ +
+
+
    #[compatible(JsonInput, SAT)]
+
+
+
+ 43 +
+
+ +
+
+
    Not(Metadata, Box<Expression>),
+
+
+
+ 44 +
+
+ +
+
+

+            
+
+
+ 45 +
+
+ +
+
+
    #[compatible(JsonInput, SAT)]
+
+
+
+ 46 +
+
+ +
+
+
    Or(Metadata, Vec<Expression>),
+
+
+
+ 47 +
+
+ +
+
+

+            
+
+
+ 48 +
+
+ +
+
+
    #[compatible(JsonInput, SAT)]
+
+
+
+ 49 +
+
+ +
+
+
    And(Metadata, Vec<Expression>),
+
+
+
+ 50 +
+
+ +
+
+

+            
+
+
+ 51 +
+
+ +
+
+
    #[compatible(JsonInput)]
+
+
+
+ 52 +
+
+ +
+
+
    Eq(Metadata, Box<Expression>, Box<Expression>),
+
+
+
+ 53 +
+
+ +
+
+

+            
+
+
+ 54 +
+
+ +
+
+
    #[compatible(JsonInput)]
+
+
+
+ 55 +
+
+ +
+
+
    Neq(Metadata, Box<Expression>, Box<Expression>),
+
+
+
+ 56 +
+
+ +
+
+

+            
+
+
+ 57 +
+
+ +
+
+
    #[compatible(JsonInput)]
+
+
+
+ 58 +
+
+ +
+
+
    Geq(Metadata, Box<Expression>, Box<Expression>),
+
+
+
+ 59 +
+
+ +
+
+

+            
+
+
+ 60 +
+
+ +
+
+
    #[compatible(JsonInput)]
+
+
+
+ 61 +
+
+ +
+
+
    Leq(Metadata, Box<Expression>, Box<Expression>),
+
+
+
+ 62 +
+
+ +
+
+

+            
+
+
+ 63 +
+
+ +
+
+
    #[compatible(JsonInput)]
+
+
+
+ 64 +
+
+ +
+
+
    Gt(Metadata, Box<Expression>, Box<Expression>),
+
+
+
+ 65 +
+
+ +
+
+

+            
+
+
+ 66 +
+
+ +
+
+
    #[compatible(JsonInput)]
+
+
+
+ 67 +
+
+ +
+
+
    Lt(Metadata, Box<Expression>, Box<Expression>),
+
+
+
+ 68 +
+
+ +
+
+

+            
+
+
+ 69 +
+
+ +
+
+
    /* Flattened SumEq.
+
+
+
+ 70 +
+
+ +
+
+
     *
+
+
+
+ 71 +
+
+ +
+
+
     * Note: this is an intermediary step that's used in the process of converting from conjure model to minion.
+
+
+
+ 72 +
+
+ +
+
+
     * This is NOT a valid expression in either Essence or minion.
+
+
+
+ 73 +
+
+ +
+
+
     *
+
+
+
+ 74 +
+
+ +
+
+
     * ToDo: This is a stop gap solution. Eventually it may be better to have multiple constraints instead? (gs248)
+
+
+
+ 75 +
+
+ +
+
+
     */
+
+
+
+ 76 +
+
+ +
+
+
    SumEq(Metadata, Vec<Expression>, Box<Expression>),
+
+
+
+ 77 +
+
+ +
+
+

+            
+
+
+ 78 +
+
+ +
+
+
    // Flattened Constraints
+
+
+
+ 79 +
+
+ +
+
+
    #[compatible(Minion)]
+
+
+
+ 80 +
+
+ +
+
+
    SumGeq(Metadata, Vec<Expression>, Box<Expression>),
+
+
+
+ 81 +
+
+ +
+
+

+            
+
+
+ 82 +
+
+ +
+
+
    #[compatible(Minion)]
+
+
+
+ 83 +
+
+ +
+
+
    SumLeq(Metadata, Vec<Expression>, Box<Expression>),
+
+
+
+ 84 +
+
+ +
+
+

+            
+
+
+ 85 +
+
+ +
+
+
    #[compatible(Minion)]
+
+
+
+ 86 +
+
+ +
+
+
    Ineq(Metadata, Box<Expression>, Box<Expression>, Box<Expression>),
+
+
+
+ 87 +
+
+ +
+
+

+            
+
+
+ 88 +
+
+ +
+
+
    // #[compatible(Minion)]
+
+
+
+ 89 +
+
+ +
+
+
    // DivEq(Metadata, Box<Expression>, Box<Expression>, Box<Expression>),
+
+
+
+ 90 +
+
+ +
+
+
    #[compatible(Minion)]
+
+
+
+ 91 +
+
+ +
+
+
    AllDiff(Metadata, Vec<Expression>),
+
+
+
+ 92 +
+
+ +
+
+
}
+
+
+
+ 93 +
+
+ +
+
+

+            
+
+
+ 94 +
+
+ +
+
+
impl Expression {
+
+
+
+ 95 +
+
+ 225 +
+
+
    pub fn bounds(&self, vars: &SymbolTable) -> Option<(i32, i32)> {
+
+
+
+ 96 +
+
+ +
+
+
        match self {
+
+
+
+ 97 +
+
+ 150 +
+
+
            Expression::Reference(_, name) => vars.get(name).and_then(|v| v.domain.min_max_i32()),
+
+
+
+ 98 +
+
+ +
+
+
            Expression::Constant(_, Constant::Int(i)) => Some((*i, *i)),
+
+
+
+ 99 +
+
+ +
+
+
            Expression::Sum(_, exprs) => {
+
+
+
+ 100 +
+
+ +
+
+
                if exprs.is_empty() {
+
+
+
+ 101 +
+
+ +
+
+
                    return None;
+
+
+
+ 102 +
+
+ +
+
+
                }
+
+
+
+ 103 +
+
+ +
+
+
                let (mut min, mut max) = (0, 0);
+
+
+
+ 104 +
+
+ +
+
+
                for e in exprs {
+
+
+
+ 105 +
+
+ +
+
+
                    if let Some((e_min, e_max)) = e.bounds(vars) {
+
+
+
+ 106 +
+
+ +
+
+
                        min += e_min;
+
+
+
+ 107 +
+
+ +
+
+
                        max += e_max;
+
+
+
+ 108 +
+
+ +
+
+
                    } else {
+
+
+
+ 109 +
+
+ +
+
+
                        return None;
+
+
+
+ 110 +
+
+ +
+
+
                    }
+
+
+
+ 111 +
+
+ +
+
+
                }
+
+
+
+ 112 +
+
+ +
+
+
                Some((min, max))
+
+
+
+ 113 +
+
+ +
+
+
            }
+
+
+
+ 114 +
+
+ 75 +
+
+
            Expression::Min(_, exprs) => {
+
+
+
+ 115 +
+
+ 75 +
+
+
                if exprs.is_empty() {
+
+
+
+ 116 +
+
+ +
+
+
                    return None;
+
+
+
+ 117 +
+
+ 75 +
+
+
                }
+
+
+
+ 118 +
+
+ 75 +
+
+
                let bounds = exprs
+
+
+
+ 119 +
+
+ 75 +
+
+
                    .iter()
+
+
+
+ 120 +
+
+ 150 +
+
+
                    .map(|e| e.bounds(vars))
+
+
+
+ 121 +
+
+ 75 +
+
+
                    .collect::<Option<Vec<(i32, i32)>>>()?;
+
+
+
+ 122 +
+
+ +
+
+
                Some((
+
+
+
+ 123 +
+
+ 150 +
+
+
                    bounds.iter().map(|(min, _)| *min).min()?,
+
+
+
+ 124 +
+
+ 150 +
+
+
                    bounds.iter().map(|(_, max)| *max).min()?,
+
+
+
+ 125 +
+
+ +
+
+
                ))
+
+
+
+ 126 +
+
+ +
+
+
            }
+
+
+
+ 127 +
+
+ +
+
+
            _ => todo!(),
+
+
+
+ 128 +
+
+ +
+
+
        }
+
+
+
+ 129 +
+
+ 225 +
+
+
    }
+
+
+
+ 130 +
+
+ +
+
+
}
+
+
+
+ 131 +
+
+ +
+
+

+            
+
+
+ 132 +
+
+ +
+
+
fn display_expressions(expressions: &[Expression]) -> String {
+
+
+
+ 133 +
+
+ +
+
+
    if expressions.len() <= 3 {
+
+
+
+ 134 +
+
+ +
+
+
        format!(
+
+
+
+ 135 +
+
+ +
+
+
            "[{}]",
+
+
+
+ 136 +
+
+ +
+
+
            expressions
+
+
+
+ 137 +
+
+ +
+
+
                .iter()
+
+
+
+ 138 +
+
+ +
+
+
                .map(|e| e.to_string())
+
+
+
+ 139 +
+
+ +
+
+
                .collect::<Vec<String>>()
+
+
+
+ 140 +
+
+ +
+
+
                .join(", ")
+
+
+
+ 141 +
+
+ +
+
+
        )
+
+
+
+ 142 +
+
+ +
+
+
    } else {
+
+
+
+ 143 +
+
+ +
+
+
        format!(
+
+
+
+ 144 +
+
+ +
+
+
            "[{}..{}]",
+
+
+
+ 145 +
+
+ +
+
+
            expressions[0],
+
+
+
+ 146 +
+
+ +
+
+
            expressions[expressions.len() - 1]
+
+
+
+ 147 +
+
+ +
+
+
        )
+
+
+
+ 148 +
+
+ +
+
+
    }
+
+
+
+ 149 +
+
+ +
+
+
}
+
+
+
+ 150 +
+
+ +
+
+

+            
+
+
+ 151 +
+
+ +
+
+
impl Display for Expression {
+
+
+
+ 152 +
+
+ +
+
+
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+
+
+
+ 153 +
+
+ +
+
+
        match &self {
+
+
+
+ 154 +
+
+ +
+
+
            Expression::Constant(metadata, c) => write!(f, "Constant({}, {})", metadata, c),
+
+
+
+ 155 +
+
+ +
+
+
            Expression::Reference(metadata, name) => write!(f, "Reference({}, {})", metadata, name),
+
+
+
+ 156 +
+
+ +
+
+
            Expression::Nothing => write!(f, "Nothing"),
+
+
+
+ 157 +
+
+ +
+
+
            Expression::Sum(metadata, expressions) => {
+
+
+
+ 158 +
+
+ +
+
+
                write!(f, "Sum({}, {})", metadata, display_expressions(expressions))
+
+
+
+ 159 +
+
+ +
+
+
            }
+
+
+
+ 160 +
+
+ +
+
+
            Expression::Not(metadata, expr_box) => {
+
+
+
+ 161 +
+
+ +
+
+
                write!(f, "Not({}, {})", metadata, expr_box.clone())
+
+
+
+ 162 +
+
+ +
+
+
            }
+
+
+
+ 163 +
+
+ +
+
+
            Expression::Or(metadata, expressions) => {
+
+
+
+ 164 +
+
+ +
+
+
                write!(f, "Not({}, {})", metadata, display_expressions(expressions))
+
+
+
+ 165 +
+
+ +
+
+
            }
+
+
+
+ 166 +
+
+ +
+
+
            Expression::And(metadata, expressions) => {
+
+
+
+ 167 +
+
+ +
+
+
                write!(f, "And({}, {})", metadata, display_expressions(expressions))
+
+
+
+ 168 +
+
+ +
+
+
            }
+
+
+
+ 169 +
+
+ +
+
+
            Expression::Eq(metadata, box1, box2) => {
+
+
+
+ 170 +
+
+ +
+
+
                write!(f, "Eq({}, {}, {})", metadata, box1.clone(), box2.clone())
+
+
+
+ 171 +
+
+ +
+
+
            }
+
+
+
+ 172 +
+
+ +
+
+
            Expression::Neq(metadata, box1, box2) => {
+
+
+
+ 173 +
+
+ +
+
+
                write!(f, "Neq({}, {}, {})", metadata, box1.clone(), box2.clone())
+
+
+
+ 174 +
+
+ +
+
+
            }
+
+
+
+ 175 +
+
+ +
+
+
            Expression::Geq(metadata, box1, box2) => {
+
+
+
+ 176 +
+
+ +
+
+
                write!(f, "Geq({}, {}, {})", metadata, box1.clone(), box2.clone())
+
+
+
+ 177 +
+
+ +
+
+
            }
+
+
+
+ 178 +
+
+ +
+
+
            Expression::Leq(metadata, box1, box2) => {
+
+
+
+ 179 +
+
+ +
+
+
                write!(f, "Leq({}, {}, {})", metadata, box1.clone(), box2.clone())
+
+
+
+ 180 +
+
+ +
+
+
            }
+
+
+
+ 181 +
+
+ +
+
+
            Expression::Gt(metadata, box1, box2) => {
+
+
+
+ 182 +
+
+ +
+
+
                write!(f, "Gt({}, {}, {})", metadata, box1.clone(), box2.clone())
+
+
+
+ 183 +
+
+ +
+
+
            }
+
+
+
+ 184 +
+
+ +
+
+
            Expression::Lt(metadata, box1, box2) => {
+
+
+
+ 185 +
+
+ +
+
+
                write!(f, "Lt({}, {}, {})", metadata, box1.clone(), box2.clone())
+
+
+
+ 186 +
+
+ +
+
+
            }
+
+
+
+ 187 +
+
+ +
+
+
            Expression::SumGeq(metadata, box1, box2) => {
+
+
+
+ 188 +
+
+ +
+
+
                write!(
+
+
+
+ 189 +
+
+ +
+
+
                    f,
+
+
+
+ 190 +
+
+ +
+
+
                    "SumGeq({}, {}. {})",
+
+
+
+ 191 +
+
+ +
+
+
                    metadata,
+
+
+
+ 192 +
+
+ +
+
+
                    display_expressions(box1),
+
+
+
+ 193 +
+
+ +
+
+
                    box2.clone()
+
+
+
+ 194 +
+
+ +
+
+
                )
+
+
+
+ 195 +
+
+ +
+
+
            }
+
+
+
+ 196 +
+
+ +
+
+
            Expression::SumLeq(metadata, box1, box2) => {
+
+
+
+ 197 +
+
+ +
+
+
                write!(
+
+
+
+ 198 +
+
+ +
+
+
                    f,
+
+
+
+ 199 +
+
+ +
+
+
                    "SumLeq({}, {}, {})",
+
+
+
+ 200 +
+
+ +
+
+
                    metadata,
+
+
+
+ 201 +
+
+ +
+
+
                    display_expressions(box1),
+
+
+
+ 202 +
+
+ +
+
+
                    box2.clone()
+
+
+
+ 203 +
+
+ +
+
+
                )
+
+
+
+ 204 +
+
+ +
+
+
            }
+
+
+
+ 205 +
+
+ +
+
+
            Expression::Ineq(metadata, box1, box2, box3) => write!(
+
+
+
+ 206 +
+
+ +
+
+
                f,
+
+
+
+ 207 +
+
+ +
+
+
                "Ineq({}, {}, {}, {})",
+
+
+
+ 208 +
+
+ +
+
+
                metadata,
+
+
+
+ 209 +
+
+ +
+
+
                box1.clone(),
+
+
+
+ 210 +
+
+ +
+
+
                box2.clone(),
+
+
+
+ 211 +
+
+ +
+
+
                box3.clone()
+
+
+
+ 212 +
+
+ +
+
+
            ),
+
+
+
+ 213 +
+
+ +
+
+
            #[allow(unreachable_patterns)]
+
+
+
+ 214 +
+
+ +
+
+
            _ => write!(f, "Expression::Unknown"),
+
+
+
+ 215 +
+
+ +
+
+
        }
+
+
+
+ 216 +
+
+ +
+
+
    }
+
+
+
+ 217 +
+
+ +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/index.html new file mode 100644 index 0000000000..0067ddb354 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/index.html @@ -0,0 +1,170 @@ + + + + + Grcov report - crates/conjure_core/src/ast + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
constants.rs + + 68.75% + + + 68.75% + + 11 / 16 + 13.16%5 / 38
domains.rs + + 33.33% + + + 33.33% + + 17 / 51 + 11.69%9 / 77
expressions.rs + + 13.54% + + + 13.54% + + 13 / 96 + 11.24%38 / 338
symbol_table.rs + + 100% + + + 100% + + 6 / 6 + 12.5%4 / 32
variables.rs + + 21.05% + + + 21.05% + + 4 / 19 + 10.53%4 / 38
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/symbol_table.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/symbol_table.rs.html new file mode 100644 index 0000000000..6fb319b356 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/symbol_table.rs.html @@ -0,0 +1,409 @@ + + + + + Grcov report - symbol_table.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use std::collections::HashMap;
+
+
+
+ 2 +
+
+ +
+
+
use std::fmt::Display;
+
+
+
+ 3 +
+
+ +
+
+

+            
+
+
+ 4 +
+
+ +
+
+
use serde::{Deserialize, Serialize};
+
+
+
+ 5 +
+
+ +
+
+

+            
+
+
+ 6 +
+
+ +
+
+
use crate::ast::variables::DecisionVariable;
+
+
+
+ 7 +
+
+ +
+
+

+            
+
+
+ 8 +
+
+ 1730 +
+
+
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
+
+
+
+ 9 +
+
+ +
+
+
pub enum Name {
+
+
+
+ 10 +
+
+ +
+
+
    UserName(String),
+
+
+
+ 11 +
+
+ +
+
+
    MachineName(i32),
+
+
+
+ 12 +
+
+ +
+
+
}
+
+
+
+ 13 +
+
+ +
+
+

+            
+
+
+ 14 +
+
+ +
+
+
impl Display for Name {
+
+
+
+ 15 +
+
+ 1425 +
+
+
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+
+
+
+ 16 +
+
+ 1425 +
+
+
        match self {
+
+
+
+ 17 +
+
+ 1050 +
+
+
            Name::UserName(s) => write!(f, "UserName({})", s),
+
+
+
+ 18 +
+
+ 375 +
+
+
            Name::MachineName(i) => write!(f, "MachineName({})", i),
+
+
+
+ 19 +
+
+ +
+
+
        }
+
+
+
+ 20 +
+
+ 1425 +
+
+
    }
+
+
+
+ 21 +
+
+ +
+
+
}
+
+
+
+ 22 +
+
+ +
+
+

+            
+
+
+ 23 +
+
+ +
+
+
pub type SymbolTable = HashMap<Name, DecisionVariable>;
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/variables.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/variables.rs.html new file mode 100644 index 0000000000..f3fef336bc --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/ast/variables.rs.html @@ -0,0 +1,665 @@ + + + + + Grcov report - variables.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use std::fmt::Display;
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
use serde::{Deserialize, Serialize};
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ +
+
+
use crate::ast::domains::{Domain, Range};
+
+
+
+ 6 +
+
+ +
+
+

+            
+
+
+ 7 +
+
+ 410 +
+
+
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+
+
+
+ 8 +
+
+ +
+
+
pub struct DecisionVariable {
+
+
+
+ 9 +
+
+ +
+
+
    pub domain: Domain,
+
+
+
+ 10 +
+
+ +
+
+
}
+
+
+
+ 11 +
+
+ +
+
+

+            
+
+
+ 12 +
+
+ +
+
+
impl DecisionVariable {
+
+
+
+ 13 +
+
+ 75 +
+
+
    pub fn new(domain: Domain) -> DecisionVariable {
+
+
+
+ 14 +
+
+ 75 +
+
+
        DecisionVariable { domain }
+
+
+
+ 15 +
+
+ 75 +
+
+
    }
+
+
+
+ 16 +
+
+ +
+
+
}
+
+
+
+ 17 +
+
+ +
+
+

+            
+
+
+ 18 +
+
+ +
+
+
impl Display for DecisionVariable {
+
+
+
+ 19 +
+
+ +
+
+
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+
+
+
+ 20 +
+
+ +
+
+
        match &self.domain {
+
+
+
+ 21 +
+
+ +
+
+
            Domain::BoolDomain => write!(f, "bool"),
+
+
+
+ 22 +
+
+ +
+
+
            Domain::IntDomain(ranges) => {
+
+
+
+ 23 +
+
+ +
+
+
                let mut first = true;
+
+
+
+ 24 +
+
+ +
+
+
                for r in ranges {
+
+
+
+ 25 +
+
+ +
+
+
                    if first {
+
+
+
+ 26 +
+
+ +
+
+
                        first = false;
+
+
+
+ 27 +
+
+ +
+
+
                    } else {
+
+
+
+ 28 +
+
+ +
+
+
                        write!(f, " or ")?;
+
+
+
+ 29 +
+
+ +
+
+
                    }
+
+
+
+ 30 +
+
+ +
+
+
                    match r {
+
+
+
+ 31 +
+
+ +
+
+
                        Range::Single(i) => write!(f, "{}", i)?,
+
+
+
+ 32 +
+
+ +
+
+
                        Range::Bounded(i, j) => write!(f, "{}..{}", i, j)?,
+
+
+
+ 33 +
+
+ +
+
+
                    }
+
+
+
+ 34 +
+
+ +
+
+
                }
+
+
+
+ 35 +
+
+ +
+
+
                Ok(())
+
+
+
+ 36 +
+
+ +
+
+
            }
+
+
+
+ 37 +
+
+ +
+
+
        }
+
+
+
+ 38 +
+
+ +
+
+
    }
+
+
+
+ 39 +
+
+ +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/context.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/context.rs.html new file mode 100644 index 0000000000..0d33e2580f --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/context.rs.html @@ -0,0 +1,1433 @@ + + + + + Grcov report - context.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use std::fmt::{Debug, Formatter};
+
+
+
+ 2 +
+
+ +
+
+
use std::sync::{Arc, RwLock};
+
+
+
+ 3 +
+
+ +
+
+

+            
+
+
+ 4 +
+
+ +
+
+
use derivative::Derivative;
+
+
+
+ 5 +
+
+ +
+
+
use schemars::{schema_for, JsonSchema};
+
+
+
+ 6 +
+
+ +
+
+
use serde::Serialize;
+
+
+
+ 7 +
+
+ +
+
+
use serde_with::skip_serializing_none;
+
+
+
+ 8 +
+
+ +
+
+

+            
+
+
+ 9 +
+
+ +
+
+
use crate::rule_engine::{Rule, RuleSet};
+
+
+
+ 10 +
+
+ +
+
+
use crate::solver::SolverFamily;
+
+
+
+ 11 +
+
+ +
+
+
use crate::stats::Stats;
+
+
+
+ 12 +
+
+ +
+
+

+            
+
+
+ 13 +
+
+ +
+
+
#[skip_serializing_none]
+
+
+
+ 14 +
+
+ +
+
+
#[derive(Clone, Serialize, Default, Derivative, JsonSchema)]
+
+
+
+ 15 +
+
+ +
+
+
#[serde(rename_all = "camelCase")]
+
+
+
+ 16 +
+
+ +
+
+
#[derivative(Eq, PartialEq)]
+
+
+
+ 17 +
+
+ +
+
+
#[non_exhaustive]
+
+
+
+ 18 +
+
+ +
+
+
pub struct Context<'a> {
+
+
+
+ 19 +
+
+ +
+
+
    pub target_solver_family: Option<SolverFamily>,
+
+
+
+ 20 +
+
+ +
+
+

+            
+
+
+ 21 +
+
+ +
+
+
    pub file_name: Option<String>,
+
+
+
+ 22 +
+
+ +
+
+

+            
+
+
+ 23 +
+
+ +
+
+
    pub extra_rule_set_names: Vec<&'a str>,
+
+
+
+ 24 +
+
+ +
+
+

+            
+
+
+ 25 +
+
+ +
+
+
    #[serde(skip)]
+
+
+
+ 26 +
+
+ +
+
+
    pub rules: Vec<&'a Rule<'a>>,
+
+
+
+ 27 +
+
+ +
+
+

+            
+
+
+ 28 +
+
+ +
+
+
    #[serde(skip)]
+
+
+
+ 29 +
+
+ +
+
+
    pub rule_sets: Vec<&'a RuleSet<'a>>,
+
+
+
+ 30 +
+
+ +
+
+

+            
+
+
+ 31 +
+
+ +
+
+
    #[derivative(PartialEq = "ignore")]
+
+
+
+ 32 +
+
+ +
+
+
    pub stats: Stats,
+
+
+
+ 33 +
+
+ +
+
+
}
+
+
+
+ 34 +
+
+ +
+
+

+            
+
+
+ 35 +
+
+ +
+
+
impl<'a> Context<'a> {
+
+
+
+ 36 +
+
+ +
+
+
    pub fn new(
+
+
+
+ 37 +
+
+ +
+
+
        target_solver_family: SolverFamily,
+
+
+
+ 38 +
+
+ +
+
+
        extra_rule_set_names: Vec<&'a str>,
+
+
+
+ 39 +
+
+ +
+
+
        rules: Vec<&'a Rule<'a>>,
+
+
+
+ 40 +
+
+ +
+
+
        rule_sets: Vec<&'a RuleSet<'a>>,
+
+
+
+ 41 +
+
+ +
+
+
    ) -> Self {
+
+
+
+ 42 +
+
+ +
+
+
        Context {
+
+
+
+ 43 +
+
+ +
+
+
            target_solver_family: Some(target_solver_family),
+
+
+
+ 44 +
+
+ +
+
+
            extra_rule_set_names,
+
+
+
+ 45 +
+
+ +
+
+
            rules,
+
+
+
+ 46 +
+
+ +
+
+
            rule_sets,
+
+
+
+ 47 +
+
+ +
+
+
            stats: Default::default(),
+
+
+
+ 48 +
+
+ +
+
+
            ..Default::default()
+
+
+
+ 49 +
+
+ +
+
+
        }
+
+
+
+ 50 +
+
+ +
+
+
    }
+
+
+
+ 51 +
+
+ +
+
+
}
+
+
+
+ 52 +
+
+ +
+
+

+            
+
+
+ 53 +
+
+ +
+
+
impl Context<'static> {
+
+
+
+ 54 +
+
+ +
+
+
    pub fn new_ptr(
+
+
+
+ 55 +
+
+ +
+
+
        target_solver_family: SolverFamily,
+
+
+
+ 56 +
+
+ +
+
+
        extra_rule_set_names: Vec<&'static str>,
+
+
+
+ 57 +
+
+ +
+
+
        rules: Vec<&'static Rule<'static>>,
+
+
+
+ 58 +
+
+ +
+
+
        rule_sets: Vec<&'static RuleSet<'static>>,
+
+
+
+ 59 +
+
+ +
+
+
    ) -> Arc<RwLock<Context<'static>>> {
+
+
+
+ 60 +
+
+ +
+
+
        Arc::new(RwLock::new(Context::new(
+
+
+
+ 61 +
+
+ +
+
+
            target_solver_family,
+
+
+
+ 62 +
+
+ +
+
+
            extra_rule_set_names,
+
+
+
+ 63 +
+
+ +
+
+
            rules,
+
+
+
+ 64 +
+
+ +
+
+
            rule_sets,
+
+
+
+ 65 +
+
+ +
+
+
        )))
+
+
+
+ 66 +
+
+ +
+
+
    }
+
+
+
+ 67 +
+
+ +
+
+
}
+
+
+
+ 68 +
+
+ +
+
+

+            
+
+
+ 69 +
+
+ +
+
+
impl<'a> Debug for Context<'a> {
+
+
+
+ 70 +
+
+ +
+
+
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+
+
+
+ 71 +
+
+ +
+
+
        let target_solver_family: Option<SolverFamily> = self.target_solver_family;
+
+
+
+ 72 +
+
+ +
+
+
        let extra_rule_set_names: Vec<&str> = self.extra_rule_set_names.clone();
+
+
+
+ 73 +
+
+ +
+
+
        let rules: Vec<&str> = self.rules.iter().map(|r| r.name).collect();
+
+
+
+ 74 +
+
+ +
+
+
        let rule_sets: Vec<&str> = self.rule_sets.iter().map(|r| r.name).collect();
+
+
+
+ 75 +
+
+ +
+
+

+            
+
+
+ 76 +
+
+ +
+
+
        write!(
+
+
+
+ 77 +
+
+ +
+
+
            f,
+
+
+
+ 78 +
+
+ +
+
+
            "Context {{\n\
+
+
+
+ 79 +
+
+ +
+
+
            \ttarget_solver_family: {:?}\n\
+
+
+
+ 80 +
+
+ +
+
+
            \textra_rule_set_names: {:?}\n\
+
+
+
+ 81 +
+
+ +
+
+
            \trules: {:?}\n\
+
+
+
+ 82 +
+
+ +
+
+
            \trule_sets: {:?}\n\
+
+
+
+ 83 +
+
+ +
+
+
        }}",
+
+
+
+ 84 +
+
+ +
+
+
            target_solver_family, extra_rule_set_names, rules, rule_sets
+
+
+
+ 85 +
+
+ +
+
+
        )
+
+
+
+ 86 +
+
+ +
+
+
    }
+
+
+
+ 87 +
+
+ +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/error.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/error.rs.html new file mode 100644 index 0000000000..ea9f9f0d72 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/error.rs.html @@ -0,0 +1,377 @@ + + + + + Grcov report - error.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
//! Top-level error types for Conjure-Oxide.
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
use serde_json::Error as JsonError;
+
+
+
+ 4 +
+
+ +
+
+
use thiserror::Error;
+
+
+
+ 5 +
+
+ +
+
+

+            
+
+
+ 6 +
+
+ +
+
+
pub type Result<T> = std::result::Result<T, Error>;
+
+
+
+ 7 +
+
+ +
+
+

+            
+
+
+ 8 +
+
+ +
+
+
#[derive(Debug, Error)]
+
+
+
+ 9 +
+
+ +
+
+
pub enum Error {
+
+
+
+ 10 +
+
+ +
+
+
    #[error("JSON error: {0}")]
+
+
+
+ 11 +
+
+ +
+
+
    JSON(#[from] JsonError),
+
+
+
+ 12 +
+
+ +
+
+

+            
+
+
+ 13 +
+
+ +
+
+
    #[error("Error parsing model: {0}")]
+
+
+
+ 14 +
+
+ +
+
+
    Parse(String),
+
+
+
+ 15 +
+
+ +
+
+

+            
+
+
+ 16 +
+
+ +
+
+
    #[error("{0} is not yet implemented.")]
+
+
+
+ 17 +
+
+ +
+
+
    NotImplemented(String),
+
+
+
+ 18 +
+
+ +
+
+

+            
+
+
+ 19 +
+
+ +
+
+
    #[error(transparent)]
+
+
+
+ 20 +
+
+ +
+
+
    Other(#[from] anyhow::Error),
+
+
+
+ 21 +
+
+ +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/index.html new file mode 100644 index 0000000000..2ba09f9e57 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/index.html @@ -0,0 +1,146 @@ + + + + + Grcov report - crates/conjure_core/src + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
context.rs + + 0% + + + 0% + + 0 / 46 + 0%0 / 18
error.rs + + 0% + + + 0% + + 0 / 1 + 0%0 / 12
metadata.rs + + 40% + + + 40% + + 4 / 10 + 9.76%4 / 41
model.rs + + 77.42% + + + 77.42% + + 48 / 62 + 15.38%14 / 91
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/metadata.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/metadata.rs.html new file mode 100644 index 0000000000..77b0da4a47 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/metadata.rs.html @@ -0,0 +1,665 @@ + + + + + Grcov report - metadata.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use std::fmt::{Debug, Display};
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
use serde::{Deserialize, Serialize};
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ 3020 +
+
+
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
+
+
+
+ 6 +
+
+ +
+
+
pub struct Metadata {
+
+
+
+ 7 +
+
+ +
+
+
    pub dirtyclean: bool,
+
+
+
+ 8 +
+
+ +
+
+
}
+
+
+
+ 9 +
+
+ +
+
+

+            
+
+
+ 10 +
+
+ +
+
+
impl Default for Metadata {
+
+
+
+ 11 +
+
+ +
+
+
    fn default() -> Self {
+
+
+
+ 12 +
+
+ +
+
+
        Self::new()
+
+
+
+ 13 +
+
+ +
+
+
    }
+
+
+
+ 14 +
+
+ +
+
+
}
+
+
+
+ 15 +
+
+ +
+
+

+            
+
+
+ 16 +
+
+ +
+
+
impl Metadata {
+
+
+
+ 17 +
+
+ 6150 +
+
+
    pub fn new() -> Metadata {
+
+
+
+ 18 +
+
+ 6150 +
+
+
        Metadata { dirtyclean: false }
+
+
+
+ 19 +
+
+ 6150 +
+
+
    }
+
+
+
+ 20 +
+
+ +
+
+
}
+
+
+
+ 21 +
+
+ +
+
+

+            
+
+
+ 22 +
+
+ +
+
+
impl Display for Metadata {
+
+
+
+ 23 +
+
+ +
+
+
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+
+
+
+ 24 +
+
+ +
+
+
        write!(f, "Metadata")
+
+
+
+ 25 +
+
+ +
+
+
    }
+
+
+
+ 26 +
+
+ +
+
+
}
+
+
+
+ 27 +
+
+ +
+
+

+            
+
+
+ 28 +
+
+ +
+
+
// impl<T> Display for Metadata<T> where T: for<'a> MetadataKind<'a> {
+
+
+
+ 29 +
+
+ +
+
+
//     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+
+
+
+ 30 +
+
+ +
+
+
//         write!(f, "Metadata")
+
+
+
+ 31 +
+
+ +
+
+
//     }
+
+
+
+ 32 +
+
+ +
+
+
// }
+
+
+
+ 33 +
+
+ +
+
+

+            
+
+
+ 34 +
+
+ +
+
+
//
+
+
+
+ 35 +
+
+ +
+
+
// impl<T> Metadata<T> where T: for<'a> MetadataKind<'a> {
+
+
+
+ 36 +
+
+ +
+
+
//     fn new(a: T) -> Metadata<T> {
+
+
+
+ 37 +
+
+ +
+
+
//         Metadata { a }
+
+
+
+ 38 +
+
+ +
+
+
//     }
+
+
+
+ 39 +
+
+ +
+
+
// }
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/model.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/model.rs.html new file mode 100644 index 0000000000..0f8e60548f --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/model.rs.html @@ -0,0 +1,1657 @@ + + + + + Grcov report - model.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use std::cell::RefCell;
+
+
+
+ 2 +
+
+ +
+
+
use std::fmt::Debug;
+
+
+
+ 3 +
+
+ +
+
+
use std::sync::{Arc, RwLock};
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ +
+
+
use derivative::Derivative;
+
+
+
+ 6 +
+
+ +
+
+
use serde::{Deserialize, Serialize};
+
+
+
+ 7 +
+
+ +
+
+
use serde_with::serde_as;
+
+
+
+ 8 +
+
+ +
+
+

+            
+
+
+ 9 +
+
+ +
+
+
use crate::ast::{DecisionVariable, Domain, Expression, Name, SymbolTable};
+
+
+
+ 10 +
+
+ +
+
+
use crate::context::Context;
+
+
+
+ 11 +
+
+ +
+
+
use crate::metadata::Metadata;
+
+
+
+ 12 +
+
+ +
+
+

+            
+
+
+ 13 +
+
+ +
+
+
#[serde_as]
+
+
+
+ 14 +
+
+ 630 +
+
+
#[derive(Derivative, Clone, Debug, Serialize, Deserialize)]
+
+
+
+ 15 +
+
+ +
+
+
#[derivative(PartialEq, Eq)]
+
+
+
+ 16 +
+
+ +
+
+
pub struct Model {
+
+
+
+ 17 +
+
+ +
+
+
    #[serde_as(as = "Vec<(_, _)>")]
+
+
+
+ 18 +
+
+ +
+
+
    pub variables: SymbolTable,
+
+
+
+ 19 +
+
+ +
+
+
    pub constraints: Expression,
+
+
+
+ 20 +
+
+ +
+
+
    #[serde(skip)]
+
+
+
+ 21 +
+
+ +
+
+
    #[derivative(PartialEq = "ignore")]
+
+
+
+ 22 +
+
+ +
+
+
    pub context: Arc<RwLock<Context<'static>>>,
+
+
+
+ 23 +
+
+ +
+
+
    next_var: RefCell<i32>,
+
+
+
+ 24 +
+
+ +
+
+
}
+
+
+
+ 25 +
+
+ +
+
+

+            
+
+
+ 26 +
+
+ +
+
+
impl Model {
+
+
+
+ 27 +
+
+ 6900 +
+
+
    pub fn new(
+
+
+
+ 28 +
+
+ 6900 +
+
+
        variables: SymbolTable,
+
+
+
+ 29 +
+
+ 6900 +
+
+
        constraints: Expression,
+
+
+
+ 30 +
+
+ 6900 +
+
+
        context: Arc<RwLock<Context<'static>>>,
+
+
+
+ 31 +
+
+ 6900 +
+
+
    ) -> Model {
+
+
+
+ 32 +
+
+ 6900 +
+
+
        Model {
+
+
+
+ 33 +
+
+ 6900 +
+
+
            variables,
+
+
+
+ 34 +
+
+ 6900 +
+
+
            constraints,
+
+
+
+ 35 +
+
+ 6900 +
+
+
            context,
+
+
+
+ 36 +
+
+ 6900 +
+
+
            next_var: RefCell::new(0),
+
+
+
+ 37 +
+
+ 6900 +
+
+
        }
+
+
+
+ 38 +
+
+ 6900 +
+
+
    }
+
+
+
+ 39 +
+
+ +
+
+

+            
+
+
+ 40 +
+
+ 6840 +
+
+
    pub fn new_empty(context: Arc<RwLock<Context<'static>>>) -> Model {
+
+
+
+ 41 +
+
+ 6840 +
+
+
        Model::new(Default::default(), Expression::Nothing, context)
+
+
+
+ 42 +
+
+ 6840 +
+
+
    }
+
+
+
+ 43 +
+
+ +
+
+
    // Function to update a DecisionVariable based on its Name
+
+
+
+ 44 +
+
+ 15 +
+
+
    pub fn update_domain(&mut self, name: &Name, new_domain: Domain) {
+
+
+
+ 45 +
+
+ 15 +
+
+
        if let Some(decision_var) = self.variables.get_mut(name) {
+
+
+
+ 46 +
+
+ 15 +
+
+
            decision_var.domain = new_domain;
+
+
+
+ 47 +
+
+ 15 +
+
+
        }
+
+
+
+ 48 +
+
+ 15 +
+
+
    }
+
+
+
+ 49 +
+
+ +
+
+

+            
+
+
+ 50 +
+
+ +
+
+
    pub fn get_domain(&self, name: &Name) -> Option<&Domain> {
+
+
+
+ 51 +
+
+ +
+
+
        self.variables.get(name).map(|v| &v.domain)
+
+
+
+ 52 +
+
+ +
+
+
    }
+
+
+
+ 53 +
+
+ +
+
+

+            
+
+
+ 54 +
+
+ +
+
+
    // Function to add a new DecisionVariable to the Model
+
+
+
+ 55 +
+
+ 375 +
+
+
    pub fn add_variable(&mut self, name: Name, decision_var: DecisionVariable) {
+
+
+
+ 56 +
+
+ 375 +
+
+
        self.variables.insert(name, decision_var);
+
+
+
+ 57 +
+
+ 375 +
+
+
    }
+
+
+
+ 58 +
+
+ +
+
+

+            
+
+
+ 59 +
+
+ 360 +
+
+
    pub fn get_constraints_vec(&self) -> Vec<Expression> {
+
+
+
+ 60 +
+
+ 360 +
+
+
        match &self.constraints {
+
+
+
+ 61 +
+
+ 120 +
+
+
            Expression::And(_, constraints) => constraints.clone(),
+
+
+
+ 62 +
+
+ 180 +
+
+
            Expression::Nothing => vec![],
+
+
+
+ 63 +
+
+ 60 +
+
+
            _ => vec![self.constraints.clone()],
+
+
+
+ 64 +
+
+ +
+
+
        }
+
+
+
+ 65 +
+
+ 360 +
+
+
    }
+
+
+
+ 66 +
+
+ +
+
+

+            
+
+
+ 67 +
+
+ 180 +
+
+
    pub fn set_constraints(&mut self, constraints: Vec<Expression>) {
+
+
+
+ 68 +
+
+ 180 +
+
+
        if constraints.is_empty() {
+
+
+
+ 69 +
+
+ +
+
+
            self.constraints = Expression::Nothing;
+
+
+
+ 70 +
+
+ 180 +
+
+
        } else if constraints.len() == 1 {
+
+
+
+ 71 +
+
+ 150 +
+
+
            self.constraints = constraints[0].clone();
+
+
+
+ 72 +
+
+ 150 +
+
+
        } else {
+
+
+
+ 73 +
+
+ 30 +
+
+
            self.constraints = Expression::And(Metadata::new(), constraints);
+
+
+
+ 74 +
+
+ 30 +
+
+
        }
+
+
+
+ 75 +
+
+ 180 +
+
+
    }
+
+
+
+ 76 +
+
+ +
+
+

+            
+
+
+ 77 +
+
+ +
+
+
    pub fn set_context(&mut self, context: Arc<RwLock<Context<'static>>>) {
+
+
+
+ 78 +
+
+ +
+
+
        self.context = context;
+
+
+
+ 79 +
+
+ +
+
+
    }
+
+
+
+ 80 +
+
+ +
+
+

+            
+
+
+ 81 +
+
+ +
+
+
    pub fn add_constraint(&mut self, expression: Expression) {
+
+
+
+ 82 +
+
+ +
+
+
        // ToDo (gs248) - there is no checking whatsoever
+
+
+
+ 83 +
+
+ +
+
+
        // We need to properly validate the expression but this is just for testing
+
+
+
+ 84 +
+
+ +
+
+
        let mut constraints = self.get_constraints_vec();
+
+
+
+ 85 +
+
+ +
+
+
        constraints.push(expression);
+
+
+
+ 86 +
+
+ +
+
+
        self.set_constraints(constraints);
+
+
+
+ 87 +
+
+ +
+
+
    }
+
+
+
+ 88 +
+
+ +
+
+

+            
+
+
+ 89 +
+
+ 180 +
+
+
    pub fn add_constraints(&mut self, expressions: Vec<Expression>) {
+
+
+
+ 90 +
+
+ 180 +
+
+
        let mut constraints = self.get_constraints_vec();
+
+
+
+ 91 +
+
+ 180 +
+
+
        constraints.extend(expressions);
+
+
+
+ 92 +
+
+ 180 +
+
+
        self.set_constraints(constraints);
+
+
+
+ 93 +
+
+ 180 +
+
+
    }
+
+
+
+ 94 +
+
+ +
+
+

+            
+
+
+ 95 +
+
+ +
+
+
    /// Returns an arbitrary variable name that is not in the model.
+
+
+
+ 96 +
+
+ 75 +
+
+
    pub fn gensym(&self) -> Name {
+
+
+
+ 97 +
+
+ 75 +
+
+
        let num = *self.next_var.borrow();
+
+
+
+ 98 +
+
+ 75 +
+
+
        *(self.next_var.borrow_mut()) += 1;
+
+
+
+ 99 +
+
+ 75 +
+
+
        Name::MachineName(num) // incremented when inserted
+
+
+
+ 100 +
+
+ 75 +
+
+
    }
+
+
+
+ 101 +
+
+ +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/parse/example_models.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/parse/example_models.rs.html new file mode 100644 index 0000000000..dda27a04c4 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/parse/example_models.rs.html @@ -0,0 +1,1769 @@ + + + + + Grcov report - example_models.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
// example_models with get_example_model function
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
use std::default;
+
+
+
+ 4 +
+
+ +
+
+
use std::path::PathBuf;
+
+
+
+ 5 +
+
+ +
+
+

+            
+
+
+ 6 +
+
+ +
+
+
use project_root::get_project_root;
+
+
+
+ 7 +
+
+ +
+
+
use walkdir::WalkDir;
+
+
+
+ 8 +
+
+ +
+
+

+            
+
+
+ 9 +
+
+ +
+
+
use crate::parse::model_from_json;
+
+
+
+ 10 +
+
+ +
+
+
use crate::Model;
+
+
+
+ 11 +
+
+ +
+
+

+            
+
+
+ 12 +
+
+ +
+
+
/// Searches recursively in `../tests/integration` folder for an `.essence` file matching the given
+
+
+
+ 13 +
+
+ +
+
+
/// filename, then uses conjure to process it into astjson, and returns the parsed model.
+
+
+
+ 14 +
+
+ +
+
+
///
+
+
+
+ 15 +
+
+ +
+
+
/// # Arguments
+
+
+
+ 16 +
+
+ +
+
+
///
+
+
+
+ 17 +
+
+ +
+
+
/// * `filename` - A string slice that holds filename without extension
+
+
+
+ 18 +
+
+ +
+
+
///
+
+
+
+ 19 +
+
+ +
+
+
/// # Returns
+
+
+
+ 20 +
+
+ +
+
+
///
+
+
+
+ 21 +
+
+ +
+
+
/// Function returns a `Result<Value, anyhow::Error>`, where `Value` is the parsed model.
+
+
+
+ 22 +
+
+ 45 +
+
+
pub fn get_example_model(filename: &str) -> Result<Model, anyhow::Error> {
+
+
+
+ 23 +
+
+ +
+
+
    // define relative path -> integration tests dir
+
+
+
+ 24 +
+
+ 45 +
+
+
    let base_dir = get_project_root()?;
+
+
+
+ 25 +
+
+ 45 +
+
+
    let mut essence_path = PathBuf::new();
+
+
+
+ 26 +
+
+ +
+
+

+            
+
+
+ 27 +
+
+ +
+
+
    // walk through directory tree recursively starting at base
+
+
+
+ 28 +
+
+ 249720 +
+
+
    for entry in WalkDir::new(base_dir).into_iter().filter_map(|e| e.ok()) {
+
+
+
+ 29 +
+
+ 249720 +
+
+
        let path = entry.path();
+
+
+
+ 30 +
+
+ 249720 +
+
+
        if path.is_file()
+
+
+
+ 31 +
+
+ 211410 +
+
+
            && path.extension().map_or(false, |e| e == "essence")
+
+
+
+ 32 +
+
+ 225 +
+
+
            && path.file_stem() == Some(std::ffi::OsStr::new(filename))
+
+
+
+ 33 +
+
+ +
+
+
        {
+
+
+
+ 34 +
+
+ 30 +
+
+
            essence_path = path.to_path_buf();
+
+
+
+ 35 +
+
+ 30 +
+
+
            break;
+
+
+
+ 36 +
+
+ 249690 +
+
+
        }
+
+
+
+ 37 +
+
+ +
+
+
    }
+
+
+
+ 38 +
+
+ +
+
+

+            
+
+
+ 39 +
+
+ +
+
+
    //println!("PATH TO FILE: {}", essence_path.display());
+
+
+
+ 40 +
+
+ +
+
+

+            
+
+
+ 41 +
+
+ +
+
+
    // return error if file not found
+
+
+
+ 42 +
+
+ 45 +
+
+
    if essence_path.as_os_str().is_empty() {
+
+
+
+ 43 +
+
+ 15 +
+
+
        return Err(anyhow::Error::new(std::io::Error::new(
+
+
+
+ 44 +
+
+ 15 +
+
+
            std::io::ErrorKind::NotFound,
+
+
+
+ 45 +
+
+ 15 +
+
+
            "ERROR: File not found in any subdirectory",
+
+
+
+ 46 +
+
+ 15 +
+
+
        )));
+
+
+
+ 47 +
+
+ 30 +
+
+
    }
+
+
+
+ 48 +
+
+ 30 +
+
+

+            
+
+
+ 49 +
+
+ 30 +
+
+
    // let path = PathBuf::from(format!("../tests/integration/basic/comprehension{}.essence", filename));
+
+
+
+ 50 +
+
+ 30 +
+
+
    let mut cmd = std::process::Command::new("conjure");
+
+
+
+ 51 +
+
+ 30 +
+
+
    let output = cmd
+
+
+
+ 52 +
+
+ 30 +
+
+
        .arg("pretty")
+
+
+
+ 53 +
+
+ 30 +
+
+
        .arg("--output-format=astjson")
+
+
+
+ 54 +
+
+ 30 +
+
+
        .arg(essence_path)
+
+
+
+ 55 +
+
+ 30 +
+
+
        .output()?;
+
+
+
+ 56 +
+
+ +
+
+

+            
+
+
+ 57 +
+
+ +
+
+
    // convert Conjure's stdout from bytes to string
+
+
+
+ 58 +
+
+ 30 +
+
+
    let astjson = String::from_utf8(output.stdout)?;
+
+
+
+ 59 +
+
+ +
+
+

+            
+
+
+ 60 +
+
+ +
+
+
    //println!("ASTJSON: {}", astjson);
+
+
+
+ 61 +
+
+ +
+
+

+            
+
+
+ 62 +
+
+ +
+
+
    // parse AST JSON from desired Model format
+
+
+
+ 63 +
+
+ 30 +
+
+
    let generated_mdl = model_from_json(&astjson, Default::default())?;
+
+
+
+ 64 +
+
+ +
+
+

+            
+
+
+ 65 +
+
+ 30 +
+
+
    Ok(generated_mdl)
+
+
+
+ 66 +
+
+ 45 +
+
+
}
+
+
+
+ 67 +
+
+ +
+
+

+            
+
+
+ 68 +
+
+ +
+
+
/// Searches for an `.essence` file at the given filepath,
+
+
+
+ 69 +
+
+ +
+
+
/// then uses conjure to process it into astjson, and returns the parsed model.
+
+
+
+ 70 +
+
+ +
+
+
///
+
+
+
+ 71 +
+
+ +
+
+
/// # Arguments
+
+
+
+ 72 +
+
+ +
+
+
///
+
+
+
+ 73 +
+
+ +
+
+
/// * `filepath` - A string slice that holds the full file path
+
+
+
+ 74 +
+
+ +
+
+
///
+
+
+
+ 75 +
+
+ +
+
+
/// # Returns
+
+
+
+ 76 +
+
+ +
+
+
///
+
+
+
+ 77 +
+
+ +
+
+
/// Function returns a `Result<Value, anyhow::Error>`, where `Value` is the parsed model
+
+
+
+ 78 +
+
+ 30 +
+
+
pub fn get_example_model_by_path(filepath: &str) -> Result<Model, anyhow::Error> {
+
+
+
+ 79 +
+
+ 30 +
+
+
    let essence_path = PathBuf::from(filepath);
+
+
+
+ 80 +
+
+ 30 +
+
+

+            
+
+
+ 81 +
+
+ 30 +
+
+
    // return error if file not found
+
+
+
+ 82 +
+
+ 30 +
+
+
    if essence_path.as_os_str().is_empty() {
+
+
+
+ 83 +
+
+ 15 +
+
+
        return Err(anyhow::Error::new(std::io::Error::new(
+
+
+
+ 84 +
+
+ 15 +
+
+
            std::io::ErrorKind::NotFound,
+
+
+
+ 85 +
+
+ 15 +
+
+
            "ERROR: File not found in any subdirectory",
+
+
+
+ 86 +
+
+ 15 +
+
+
        )));
+
+
+
+ 87 +
+
+ 15 +
+
+
    }
+
+
+
+ 88 +
+
+ 15 +
+
+

+            
+
+
+ 89 +
+
+ 15 +
+
+
    // println!("PATH TO FILE: {}", essence_path.display());
+
+
+
+ 90 +
+
+ 15 +
+
+

+            
+
+
+ 91 +
+
+ 15 +
+
+
    // Command execution using 'conjure' CLI tool with provided path
+
+
+
+ 92 +
+
+ 15 +
+
+
    let mut cmd = std::process::Command::new("conjure");
+
+
+
+ 93 +
+
+ 15 +
+
+
    let output = cmd
+
+
+
+ 94 +
+
+ 15 +
+
+
        .arg("pretty")
+
+
+
+ 95 +
+
+ 15 +
+
+
        .arg("--output-format=astjson")
+
+
+
+ 96 +
+
+ 15 +
+
+
        .arg(&essence_path)
+
+
+
+ 97 +
+
+ 15 +
+
+
        .output()?;
+
+
+
+ 98 +
+
+ +
+
+

+            
+
+
+ 99 +
+
+ +
+
+
    // convert Conjure's stdout from bytes to string
+
+
+
+ 100 +
+
+ 15 +
+
+
    let astjson = String::from_utf8(output.stdout)?;
+
+
+
+ 101 +
+
+ +
+
+

+            
+
+
+ 102 +
+
+ +
+
+
    // println!("ASTJSON: {}", astjson);
+
+
+
+ 103 +
+
+ +
+
+

+            
+
+
+ 104 +
+
+ +
+
+
    // parse AST JSON into the desired Model format
+
+
+
+ 105 +
+
+ 15 +
+
+
    let generated_model = model_from_json(&astjson, Default::default())?;
+
+
+
+ 106 +
+
+ +
+
+

+            
+
+
+ 107 +
+
+ 15 +
+
+
    Ok(generated_model)
+
+
+
+ 108 +
+
+ 30 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/parse/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/parse/index.html new file mode 100644 index 0000000000..ca6a1d4e2b --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/parse/index.html @@ -0,0 +1,98 @@ + + + + + Grcov report - crates/conjure_core/src/parse + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
example_models.rs + + 100% + + + 100% + + 53 / 53 + 33.33%4 / 12
parse_model.rs + + 84.34% + + + 84.34% + + 210 / 249 + 27.08%13 / 48
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/parse/parse_model.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/parse/parse_model.rs.html new file mode 100644 index 0000000000..3d361bd0c3 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/parse/parse_model.rs.html @@ -0,0 +1,5065 @@ + + + + + Grcov report - parse_model.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use std::collections::HashMap;
+
+
+
+ 2 +
+
+ +
+
+
use std::sync::{Arc, RwLock};
+
+
+
+ 3 +
+
+ +
+
+

+            
+
+
+ 4 +
+
+ +
+
+
use serde_json::Value;
+
+
+
+ 5 +
+
+ +
+
+
use serde_json::Value as JsonValue;
+
+
+
+ 6 +
+
+ +
+
+

+            
+
+
+ 7 +
+
+ +
+
+
use crate::ast::{Constant, DecisionVariable, Domain, Expression, Name, Range};
+
+
+
+ 8 +
+
+ +
+
+
use crate::context::Context;
+
+
+
+ 9 +
+
+ +
+
+
use crate::error::{Error, Result};
+
+
+
+ 10 +
+
+ +
+
+
use crate::metadata::Metadata;
+
+
+
+ 11 +
+
+ +
+
+
use crate::Model;
+
+
+
+ 12 +
+
+ +
+
+

+            
+
+
+ 13 +
+
+ 180 +
+
+
pub fn model_from_json(str: &str, context: Arc<RwLock<Context<'static>>>) -> Result<Model> {
+
+
+
+ 14 +
+
+ 180 +
+
+
    let mut m = Model::new_empty(context);
+
+
+
+ 15 +
+
+ 180 +
+
+
    let v: JsonValue = serde_json::from_str(str)?;
+
+
+
+ 16 +
+
+ 180 +
+
+
    let statements = v["mStatements"]
+
+
+
+ 17 +
+
+ 180 +
+
+
        .as_array()
+
+
+
+ 18 +
+
+ 180 +
+
+
        .ok_or(Error::Parse("mStatements is not an array".to_owned()))?;
+
+
+
+ 19 +
+
+ +
+
+

+            
+
+
+ 20 +
+
+ 735 +
+
+
    for statement in statements {
+
+
+
+ 21 +
+
+ 555 +
+
+
        let entry = statement
+
+
+
+ 22 +
+
+ 555 +
+
+
            .as_object()
+
+
+
+ 23 +
+
+ 555 +
+
+
            .ok_or(Error::Parse("mStatements contains a non-object".to_owned()))?
+
+
+
+ 24 +
+
+ 555 +
+
+
            .iter()
+
+
+
+ 25 +
+
+ 555 +
+
+
            .next()
+
+
+
+ 26 +
+
+ 555 +
+
+
            .ok_or(Error::Parse(
+
+
+
+ 27 +
+
+ 555 +
+
+
                "mStatements contains an empty object".to_owned(),
+
+
+
+ 28 +
+
+ 555 +
+
+
            ))?;
+
+
+
+ 29 +
+
+ 555 +
+
+
        match entry.0.as_str() {
+
+
+
+ 30 +
+
+ 555 +
+
+
            "Declaration" => {
+
+
+
+ 31 +
+
+ 375 +
+
+
                let (name, var) = parse_variable(entry.1)?;
+
+
+
+ 32 +
+
+ 375 +
+
+
                m.add_variable(name, var);
+
+
+
+ 33 +
+
+ +
+
+
            }
+
+
+
+ 34 +
+
+ 180 +
+
+
            "SuchThat" => {
+
+
+
+ 35 +
+
+ 180 +
+
+
                let constraints_arr = match entry.1.as_array() {
+
+
+
+ 36 +
+
+ 180 +
+
+
                    Some(x) => x,
+
+
+
+ 37 +
+
+ +
+
+
                    None => {
+
+
+
+ 38 +
+
+ +
+
+
                        return Err(Error::Parse("SuchThat is not a vector".to_owned()));
+
+
+
+ 39 +
+
+ +
+
+
                    }
+
+
+
+ 40 +
+
+ +
+
+
                };
+
+
+
+ 41 +
+
+ +
+
+

+            
+
+
+ 42 +
+
+ 180 +
+
+
                let constraints: Vec<Expression> =
+
+
+
+ 43 +
+
+ 180 +
+
+
                    constraints_arr.iter().flat_map(parse_expression).collect();
+
+
+
+ 44 +
+
+ 180 +
+
+
                m.add_constraints(constraints);
+
+
+
+ 45 +
+
+ +
+
+
                // println!("Nb constraints {}", m.constraints.len());
+
+
+
+ 46 +
+
+ +
+
+
            }
+
+
+
+ 47 +
+
+ +
+
+
            otherwise => panic!("Unhandled Statement {:#?}", otherwise),
+
+
+
+ 48 +
+
+ +
+
+
        }
+
+
+
+ 49 +
+
+ +
+
+
    }
+
+
+
+ 50 +
+
+ +
+
+

+            
+
+
+ 51 +
+
+ 180 +
+
+
    Ok(m)
+
+
+
+ 52 +
+
+ 180 +
+
+
}
+
+
+
+ 53 +
+
+ +
+
+

+            
+
+
+ 54 +
+
+ 375 +
+
+
fn parse_variable(v: &JsonValue) -> Result<(Name, DecisionVariable)> {
+
+
+
+ 55 +
+
+ 375 +
+
+
    let arr = v
+
+
+
+ 56 +
+
+ 375 +
+
+
        .as_object()
+
+
+
+ 57 +
+
+ 375 +
+
+
        .ok_or(Error::Parse("Declaration is not an object".to_owned()))?["FindOrGiven"]
+
+
+
+ 58 +
+
+ 375 +
+
+
        .as_array()
+
+
+
+ 59 +
+
+ 375 +
+
+
        .ok_or(Error::Parse("FindOrGiven is not an array".to_owned()))?;
+
+
+
+ 60 +
+
+ 375 +
+
+
    let name = arr[1]
+
+
+
+ 61 +
+
+ 375 +
+
+
        .as_object()
+
+
+
+ 62 +
+
+ 375 +
+
+
        .ok_or(Error::Parse("FindOrGiven[1] is not an object".to_owned()))?["Name"]
+
+
+
+ 63 +
+
+ 375 +
+
+
        .as_str()
+
+
+
+ 64 +
+
+ 375 +
+
+
        .ok_or(Error::Parse(
+
+
+
+ 65 +
+
+ 375 +
+
+
            "FindOrGiven[1].Name is not a string".to_owned(),
+
+
+
+ 66 +
+
+ 375 +
+
+
        ))?;
+
+
+
+ 67 +
+
+ 375 +
+
+
    let name = Name::UserName(name.to_owned());
+
+
+
+ 68 +
+
+ 375 +
+
+
    let domain = arr[2]
+
+
+
+ 69 +
+
+ 375 +
+
+
        .as_object()
+
+
+
+ 70 +
+
+ 375 +
+
+
        .ok_or(Error::Parse("FindOrGiven[2] is not an object".to_owned()))?
+
+
+
+ 71 +
+
+ 375 +
+
+
        .iter()
+
+
+
+ 72 +
+
+ 375 +
+
+
        .next()
+
+
+
+ 73 +
+
+ 375 +
+
+
        .ok_or(Error::Parse("FindOrGiven[2] is an empty object".to_owned()))?;
+
+
+
+ 74 +
+
+ 375 +
+
+
    let domain = match domain.0.as_str() {
+
+
+
+ 75 +
+
+ 375 +
+
+
        "DomainInt" => Ok(parse_int_domain(domain.1)?),
+
+
+
+ 76 +
+
+ 105 +
+
+
        "DomainBool" => Ok(Domain::BoolDomain),
+
+
+
+ 77 +
+
+ +
+
+
        _ => Err(Error::Parse(
+
+
+
+ 78 +
+
+ +
+
+
            "FindOrGiven[2] is an unknown object".to_owned(),
+
+
+
+ 79 +
+
+ +
+
+
        )),
+
+
+
+ 80 +
+
+ +
+
+
    }?;
+
+
+
+ 81 +
+
+ 375 +
+
+
    Ok((name, DecisionVariable { domain }))
+
+
+
+ 82 +
+
+ 375 +
+
+
}
+
+
+
+ 83 +
+
+ +
+
+

+            
+
+
+ 84 +
+
+ 270 +
+
+
fn parse_int_domain(v: &JsonValue) -> Result<Domain> {
+
+
+
+ 85 +
+
+ 270 +
+
+
    let mut ranges = Vec::new();
+
+
+
+ 86 +
+
+ 270 +
+
+
    let arr = v
+
+
+
+ 87 +
+
+ 270 +
+
+
        .as_array()
+
+
+
+ 88 +
+
+ 270 +
+
+
        .ok_or(Error::Parse("DomainInt is not an array".to_owned()))?[1]
+
+
+
+ 89 +
+
+ 270 +
+
+
        .as_array()
+
+
+
+ 90 +
+
+ 270 +
+
+
        .ok_or(Error::Parse("DomainInt[1] is not an array".to_owned()))?;
+
+
+
+ 91 +
+
+ 540 +
+
+
    for range in arr {
+
+
+
+ 92 +
+
+ 270 +
+
+
        let range = range
+
+
+
+ 93 +
+
+ 270 +
+
+
            .as_object()
+
+
+
+ 94 +
+
+ 270 +
+
+
            .ok_or(Error::Parse(
+
+
+
+ 95 +
+
+ 270 +
+
+
                "DomainInt[1] contains a non-object".to_owned(),
+
+
+
+ 96 +
+
+ 270 +
+
+
            ))?
+
+
+
+ 97 +
+
+ 270 +
+
+
            .iter()
+
+
+
+ 98 +
+
+ 270 +
+
+
            .next()
+
+
+
+ 99 +
+
+ 270 +
+
+
            .ok_or(Error::Parse(
+
+
+
+ 100 +
+
+ 270 +
+
+
                "DomainInt[1] contains an empty object".to_owned(),
+
+
+
+ 101 +
+
+ 270 +
+
+
            ))?;
+
+
+
+ 102 +
+
+ 270 +
+
+
        match range.0.as_str() {
+
+
+
+ 103 +
+
+ 270 +
+
+
            "RangeBounded" => {
+
+
+
+ 104 +
+
+ 270 +
+
+
                let arr = range
+
+
+
+ 105 +
+
+ 270 +
+
+
                    .1
+
+
+
+ 106 +
+
+ 270 +
+
+
                    .as_array()
+
+
+
+ 107 +
+
+ 270 +
+
+
                    .ok_or(Error::Parse("RangeBounded is not an array".to_owned()))?;
+
+
+
+ 108 +
+
+ 270 +
+
+
                let mut nums = Vec::new();
+
+
+
+ 109 +
+
+ 540 +
+
+
                for item in arr.iter() {
+
+
+
+ 110 +
+
+ 540 +
+
+
                    let num = item["Constant"]["ConstantInt"][1]
+
+
+
+ 111 +
+
+ 540 +
+
+
                        .as_i64()
+
+
+
+ 112 +
+
+ 540 +
+
+
                        .ok_or(Error::Parse(
+
+
+
+ 113 +
+
+ 540 +
+
+
                            "Could not parse int domain constant".to_owned(),
+
+
+
+ 114 +
+
+ 540 +
+
+
                        ))?;
+
+
+
+ 115 +
+
+ 540 +
+
+
                    let num32 = i32::try_from(num).map_err(|_| {
+
+
+
+ 116 +
+
+ +
+
+
                        Error::Parse("Could not parse int domain constant".to_owned())
+
+
+
+ 117 +
+
+ 540 +
+
+
                    })?;
+
+
+
+ 118 +
+
+ 540 +
+
+
                    nums.push(num32);
+
+
+
+ 119 +
+
+ +
+
+
                }
+
+
+
+ 120 +
+
+ 270 +
+
+
                ranges.push(Range::Bounded(nums[0], nums[1]));
+
+
+
+ 121 +
+
+ +
+
+
            }
+
+
+
+ 122 +
+
+ +
+
+
            "RangeSingle" => {
+
+
+
+ 123 +
+
+ +
+
+
                let num = &range.1["Constant"]["ConstantInt"][1]
+
+
+
+ 124 +
+
+ +
+
+
                    .as_i64()
+
+
+
+ 125 +
+
+ +
+
+
                    .ok_or(Error::Parse(
+
+
+
+ 126 +
+
+ +
+
+
                        "Could not parse int domain constant".to_owned(),
+
+
+
+ 127 +
+
+ +
+
+
                    ))?;
+
+
+
+ 128 +
+
+ +
+
+
                let num32 = i32::try_from(*num)
+
+
+
+ 129 +
+
+ +
+
+
                    .map_err(|_| Error::Parse("Could not parse int domain constant".to_owned()))?;
+
+
+
+ 130 +
+
+ +
+
+
                ranges.push(Range::Single(num32));
+
+
+
+ 131 +
+
+ +
+
+
            }
+
+
+
+ 132 +
+
+ +
+
+
            _ => {
+
+
+
+ 133 +
+
+ +
+
+
                return Err(Error::Parse(
+
+
+
+ 134 +
+
+ +
+
+
                    "DomainInt[1] contains an unknown object".to_owned(),
+
+
+
+ 135 +
+
+ +
+
+
                ))
+
+
+
+ 136 +
+
+ +
+
+
            }
+
+
+
+ 137 +
+
+ +
+
+
        }
+
+
+
+ 138 +
+
+ +
+
+
    }
+
+
+
+ 139 +
+
+ 270 +
+
+
    Ok(Domain::IntDomain(ranges))
+
+
+
+ 140 +
+
+ 270 +
+
+
}
+
+
+
+ 141 +
+
+ +
+
+

+            
+
+
+ 142 +
+
+ +
+
+
// this needs an explicit type signature to force the closures to have the same type
+
+
+
+ 143 +
+
+ +
+
+
type BinOp = Box<dyn Fn(Metadata, Box<Expression>, Box<Expression>) -> Expression>;
+
+
+
+ 144 +
+
+ +
+
+
type UnaryOp = Box<dyn Fn(Metadata, Box<Expression>) -> Expression>;
+
+
+
+ 145 +
+
+ +
+
+
type VecOp = Box<dyn Fn(Metadata, Vec<Expression>) -> Expression>;
+
+
+
+ 146 +
+
+ +
+
+

+            
+
+
+ 147 +
+
+ 840 +
+
+
fn parse_expression(obj: &JsonValue) -> Option<Expression> {
+
+
+
+ 148 +
+
+ 840 +
+
+
    let binary_operators: HashMap<&str, BinOp> = [
+
+
+
+ 149 +
+
+ 840 +
+
+
        (
+
+
+
+ 150 +
+
+ 840 +
+
+
            "MkOpEq",
+
+
+
+ 151 +
+
+ 840 +
+
+
            Box::new(Expression::Eq) as Box<dyn Fn(_, _, _) -> _>,
+
+
+
+ 152 +
+
+ 840 +
+
+
        ),
+
+
+
+ 153 +
+
+ 840 +
+
+
        (
+
+
+
+ 154 +
+
+ 840 +
+
+
            "MkOpNeq",
+
+
+
+ 155 +
+
+ 840 +
+
+
            Box::new(Expression::Neq) as Box<dyn Fn(_, _, _) -> _>,
+
+
+
+ 156 +
+
+ 840 +
+
+
        ),
+
+
+
+ 157 +
+
+ 840 +
+
+
        (
+
+
+
+ 158 +
+
+ 840 +
+
+
            "MkOpGeq",
+
+
+
+ 159 +
+
+ 840 +
+
+
            Box::new(Expression::Geq) as Box<dyn Fn(_, _, _) -> _>,
+
+
+
+ 160 +
+
+ 840 +
+
+
        ),
+
+
+
+ 161 +
+
+ 840 +
+
+
        (
+
+
+
+ 162 +
+
+ 840 +
+
+
            "MkOpLeq",
+
+
+
+ 163 +
+
+ 840 +
+
+
            Box::new(Expression::Leq) as Box<dyn Fn(_, _, _) -> _>,
+
+
+
+ 164 +
+
+ 840 +
+
+
        ),
+
+
+
+ 165 +
+
+ 840 +
+
+
        (
+
+
+
+ 166 +
+
+ 840 +
+
+
            "MkOpGt",
+
+
+
+ 167 +
+
+ 840 +
+
+
            Box::new(Expression::Gt) as Box<dyn Fn(_, _, _) -> _>,
+
+
+
+ 168 +
+
+ 840 +
+
+
        ),
+
+
+
+ 169 +
+
+ 840 +
+
+
        (
+
+
+
+ 170 +
+
+ 840 +
+
+
            "MkOpLt",
+
+
+
+ 171 +
+
+ 840 +
+
+
            Box::new(Expression::Lt) as Box<dyn Fn(_, _, _) -> _>,
+
+
+
+ 172 +
+
+ 840 +
+
+
        ),
+
+
+
+ 173 +
+
+ 840 +
+
+
        (
+
+
+
+ 174 +
+
+ 840 +
+
+
            "MkOpGt",
+
+
+
+ 175 +
+
+ 840 +
+
+
            Box::new(Expression::Gt) as Box<dyn Fn(_, _, _) -> _>,
+
+
+
+ 176 +
+
+ 840 +
+
+
        ),
+
+
+
+ 177 +
+
+ 840 +
+
+
        (
+
+
+
+ 178 +
+
+ 840 +
+
+
            "MkOpLt",
+
+
+
+ 179 +
+
+ 840 +
+
+
            Box::new(Expression::Lt) as Box<dyn Fn(_, _, _) -> _>,
+
+
+
+ 180 +
+
+ 840 +
+
+
        ),
+
+
+
+ 181 +
+
+ 840 +
+
+
        // (
+
+
+
+ 182 +
+
+ 840 +
+
+
        //     "MkOpDiv",
+
+
+
+ 183 +
+
+ 840 +
+
+
        //     Box::new(Expression::Div) as Box<dyn Fn(_, _, _) -> _>,
+
+
+
+ 184 +
+
+ 840 +
+
+
        // ),
+
+
+
+ 185 +
+
+ 840 +
+
+
    ]
+
+
+
+ 186 +
+
+ 840 +
+
+
    .into_iter()
+
+
+
+ 187 +
+
+ 840 +
+
+
    .collect();
+
+
+
+ 188 +
+
+ 840 +
+
+

+            
+
+
+ 189 +
+
+ 840 +
+
+
    let unary_operators: HashMap<&str, UnaryOp> = [(
+
+
+
+ 190 +
+
+ 840 +
+
+
        "MkOpNot",
+
+
+
+ 191 +
+
+ 840 +
+
+
        Box::new(Expression::Not) as Box<dyn Fn(_, _) -> _>,
+
+
+
+ 192 +
+
+ 840 +
+
+
    )]
+
+
+
+ 193 +
+
+ 840 +
+
+
    .into_iter()
+
+
+
+ 194 +
+
+ 840 +
+
+
    .collect();
+
+
+
+ 195 +
+
+ 840 +
+
+

+            
+
+
+ 196 +
+
+ 840 +
+
+
    let vec_operators: HashMap<&str, VecOp> = [
+
+
+
+ 197 +
+
+ 840 +
+
+
        (
+
+
+
+ 198 +
+
+ 840 +
+
+
            "MkOpSum",
+
+
+
+ 199 +
+
+ 840 +
+
+
            Box::new(Expression::Sum) as Box<dyn Fn(_, _) -> _>,
+
+
+
+ 200 +
+
+ 840 +
+
+
        ),
+
+
+
+ 201 +
+
+ 840 +
+
+
        (
+
+
+
+ 202 +
+
+ 840 +
+
+
            "MkOpAnd",
+
+
+
+ 203 +
+
+ 840 +
+
+
            Box::new(Expression::And) as Box<dyn Fn(_, _) -> _>,
+
+
+
+ 204 +
+
+ 840 +
+
+
        ),
+
+
+
+ 205 +
+
+ 840 +
+
+
        ("MkOpOr", Box::new(Expression::Or) as Box<dyn Fn(_, _) -> _>),
+
+
+
+ 206 +
+
+ 840 +
+
+
        (
+
+
+
+ 207 +
+
+ 840 +
+
+
            "MkOpMin",
+
+
+
+ 208 +
+
+ 840 +
+
+
            Box::new(Expression::Min) as Box<dyn Fn(_, _) -> _>,
+
+
+
+ 209 +
+
+ 840 +
+
+
        ),
+
+
+
+ 210 +
+
+ 840 +
+
+
    ]
+
+
+
+ 211 +
+
+ 840 +
+
+
    .into_iter()
+
+
+
+ 212 +
+
+ 840 +
+
+
    .collect();
+
+
+
+ 213 +
+
+ 840 +
+
+

+            
+
+
+ 214 +
+
+ 1620 +
+
+
    let mut binary_operator_names = binary_operators.iter().map(|x| x.0);
+
+
+
+ 215 +
+
+ 840 +
+
+
    let mut unary_operator_names = unary_operators.iter().map(|x| x.0);
+
+
+
+ 216 +
+
+ 840 +
+
+
    let mut vec_operator_names = vec_operators.iter().map(|x| x.0);
+
+
+
+ 217 +
+
+ +
+
+

+            
+
+
+ 218 +
+
+ 120 +
+
+
    match obj {
+
+
+
+ 219 +
+
+ 840 +
+
+
        Value::Object(op) if op.contains_key("Op") => match &op["Op"] {
+
+
+
+ 220 +
+
+ 1620 +
+
+
            Value::Object(bin_op) if binary_operator_names.any(|key| bin_op.contains_key(*key)) => {
+
+
+
+ 221 +
+
+ 180 +
+
+
                parse_bin_op(bin_op, binary_operators)
+
+
+
+ 222 +
+
+ +
+
+
            }
+
+
+
+ 223 +
+
+ 150 +
+
+
            Value::Object(un_op) if unary_operator_names.any(|key| un_op.contains_key(*key)) => {
+
+
+
+ 224 +
+
+ +
+
+
                parse_unary_op(un_op, unary_operators)
+
+
+
+ 225 +
+
+ +
+
+
            }
+
+
+
+ 226 +
+
+ 450 +
+
+
            Value::Object(vec_op) if vec_operator_names.any(|key| vec_op.contains_key(*key)) => {
+
+
+
+ 227 +
+
+ 150 +
+
+
                parse_vec_op(vec_op, vec_operators)
+
+
+
+ 228 +
+
+ +
+
+
            }
+
+
+
+ 229 +
+
+ +
+
+
            otherwise => panic!("Unhandled Op {:#?}", otherwise),
+
+
+
+ 230 +
+
+ +
+
+
        },
+
+
+
+ 231 +
+
+ 510 +
+
+
        Value::Object(refe) if refe.contains_key("Reference") => {
+
+
+
+ 232 +
+
+ 390 +
+
+
            let name = refe["Reference"].as_array()?[0].as_object()?["Name"].as_str()?;
+
+
+
+ 233 +
+
+ 390 +
+
+
            Some(Expression::Reference(
+
+
+
+ 234 +
+
+ 390 +
+
+
                Metadata::new(),
+
+
+
+ 235 +
+
+ 390 +
+
+
                Name::UserName(name.to_string()),
+
+
+
+ 236 +
+
+ 390 +
+
+
            ))
+
+
+
+ 237 +
+
+ +
+
+
        }
+
+
+
+ 238 +
+
+ 120 +
+
+
        Value::Object(constant) if constant.contains_key("Constant") => parse_constant(constant),
+
+
+
+ 239 +
+
+ +
+
+
        otherwise => panic!("Unhandled Expression {:#?}", otherwise),
+
+
+
+ 240 +
+
+ +
+
+
    }
+
+
+
+ 241 +
+
+ 840 +
+
+
}
+
+
+
+ 242 +
+
+ +
+
+

+            
+
+
+ 243 +
+
+ 180 +
+
+
fn parse_bin_op(
+
+
+
+ 244 +
+
+ 180 +
+
+
    bin_op: &serde_json::Map<String, Value>,
+
+
+
+ 245 +
+
+ 180 +
+
+
    binary_operators: HashMap<&str, BinOp>,
+
+
+
+ 246 +
+
+ 180 +
+
+
) -> Option<Expression> {
+
+
+
+ 247 +
+
+ +
+
+
    // we know there is a single key value pair in this object
+
+
+
+ 248 +
+
+ +
+
+
    // extract the value, ignore the key
+
+
+
+ 249 +
+
+ 180 +
+
+
    let (key, value) = bin_op.into_iter().next()?;
+
+
+
+ 250 +
+
+ +
+
+

+            
+
+
+ 251 +
+
+ 180 +
+
+
    let constructor = binary_operators.get(key.as_str())?;
+
+
+
+ 252 +
+
+ +
+
+

+            
+
+
+ 253 +
+
+ 180 +
+
+
    match &value {
+
+
+
+ 254 +
+
+ 180 +
+
+
        Value::Array(bin_op_args) if bin_op_args.len() == 2 => {
+
+
+
+ 255 +
+
+ 180 +
+
+
            let arg1 = parse_expression(&bin_op_args[0])?;
+
+
+
+ 256 +
+
+ 180 +
+
+
            let arg2 = parse_expression(&bin_op_args[1])?;
+
+
+
+ 257 +
+
+ 180 +
+
+
            Some(constructor(Metadata::new(), Box::new(arg1), Box::new(arg2)))
+
+
+
+ 258 +
+
+ +
+
+
        }
+
+
+
+ 259 +
+
+ +
+
+
        otherwise => panic!("Unhandled parse_bin_op {:#?}", otherwise),
+
+
+
+ 260 +
+
+ +
+
+
    }
+
+
+
+ 261 +
+
+ 180 +
+
+
}
+
+
+
+ 262 +
+
+ +
+
+

+            
+
+
+ 263 +
+
+ +
+
+
fn parse_unary_op(
+
+
+
+ 264 +
+
+ +
+
+
    un_op: &serde_json::Map<String, Value>,
+
+
+
+ 265 +
+
+ +
+
+
    unary_operators: HashMap<&str, UnaryOp>,
+
+
+
+ 266 +
+
+ +
+
+
) -> Option<Expression> {
+
+
+
+ 267 +
+
+ +
+
+
    let (key, value) = un_op.into_iter().next()?;
+
+
+
+ 268 +
+
+ +
+
+
    let constructor = unary_operators.get(key.as_str())?;
+
+
+
+ 269 +
+
+ +
+
+

+            
+
+
+ 270 +
+
+ +
+
+
    let arg = parse_expression(value)?;
+
+
+
+ 271 +
+
+ +
+
+
    Some(constructor(Metadata::new(), Box::new(arg)))
+
+
+
+ 272 +
+
+ +
+
+
}
+
+
+
+ 273 +
+
+ +
+
+

+            
+
+
+ 274 +
+
+ 150 +
+
+
fn parse_vec_op(
+
+
+
+ 275 +
+
+ 150 +
+
+
    vec_op: &serde_json::Map<String, Value>,
+
+
+
+ 276 +
+
+ 150 +
+
+
    vec_operators: HashMap<&str, VecOp>,
+
+
+
+ 277 +
+
+ 150 +
+
+
) -> Option<Expression> {
+
+
+
+ 278 +
+
+ 150 +
+
+
    let (key, value) = vec_op.into_iter().next()?;
+
+
+
+ 279 +
+
+ 150 +
+
+
    let constructor = vec_operators.get(key.as_str())?;
+
+
+
+ 280 +
+
+ +
+
+

+            
+
+
+ 281 +
+
+ 150 +
+
+
    let args_parsed: Vec<Option<Expression>> = value["AbstractLiteral"]["AbsLitMatrix"][1]
+
+
+
+ 282 +
+
+ 150 +
+
+
        .as_array()?
+
+
+
+ 283 +
+
+ 150 +
+
+
        .iter()
+
+
+
+ 284 +
+
+ 150 +
+
+
        .map(parse_expression)
+
+
+
+ 285 +
+
+ 150 +
+
+
        .collect();
+
+
+
+ 286 +
+
+ 150 +
+
+

+            
+
+
+ 287 +
+
+ 150 +
+
+
    let number_of_args = args_parsed.len();
+
+
+
+ 288 +
+
+ 150 +
+
+
    let valid_args: Vec<Expression> = args_parsed.into_iter().flatten().collect();
+
+
+
+ 289 +
+
+ 150 +
+
+
    if number_of_args != valid_args.len() {
+
+
+
+ 290 +
+
+ +
+
+
        None
+
+
+
+ 291 +
+
+ +
+
+
    } else {
+
+
+
+ 292 +
+
+ 150 +
+
+
        Some(constructor(Metadata::new(), valid_args))
+
+
+
+ 293 +
+
+ +
+
+
    }
+
+
+
+ 294 +
+
+ 150 +
+
+
}
+
+
+
+ 295 +
+
+ +
+
+

+            
+
+
+ 296 +
+
+ 120 +
+
+
fn parse_constant(constant: &serde_json::Map<String, Value>) -> Option<Expression> {
+
+
+
+ 297 +
+
+ 120 +
+
+
    match &constant["Constant"] {
+
+
+
+ 298 +
+
+ 120 +
+
+
        Value::Object(int) if int.contains_key("ConstantInt") => {
+
+
+
+ 299 +
+
+ 120 +
+
+
            let int_32: i32 = match int["ConstantInt"].as_array()?[1].as_i64()?.try_into() {
+
+
+
+ 300 +
+
+ 120 +
+
+
                Ok(x) => x,
+
+
+
+ 301 +
+
+ +
+
+
                Err(_) => {
+
+
+
+ 302 +
+
+ +
+
+
                    println!(
+
+
+
+ 303 +
+
+ +
+
+
                        "Could not convert integer constant to i32: {:#?}",
+
+
+
+ 304 +
+
+ +
+
+
                        int["ConstantInt"]
+
+
+
+ 305 +
+
+ +
+
+
                    );
+
+
+
+ 306 +
+
+ +
+
+
                    return None;
+
+
+
+ 307 +
+
+ +
+
+
                }
+
+
+
+ 308 +
+
+ +
+
+
            };
+
+
+
+ 309 +
+
+ +
+
+

+            
+
+
+ 310 +
+
+ 120 +
+
+
            Some(Expression::Constant(Metadata::new(), Constant::Int(int_32)))
+
+
+
+ 311 +
+
+ +
+
+
        }
+
+
+
+ 312 +
+
+ +
+
+
        otherwise => panic!("Unhandled parse_constant {:#?}", otherwise),
+
+
+
+ 313 +
+
+ +
+
+
    }
+
+
+
+ 314 +
+
+ 120 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/index.html new file mode 100644 index 0000000000..321ff792ef --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/index.html @@ -0,0 +1,170 @@ + + + + + Grcov report - crates/conjure_core/src/rule_engine + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
mod.rs + + 87.95% + + + 87.95% + + 73 / 83 + 28.3%15 / 53
resolve_rules.rs + + 87.14% + + + 87.14% + + 61 / 70 + 29.17%7 / 24
rewrite.rs + + 85.71% + + + 85.71% + + 54 / 63 + 22.22%4 / 18
rule.rs + + 50.75% + + + 50.75% + + 34 / 67 + 18.18%6 / 33
rule_set.rs + + 59.18% + + + 59.18% + + 58 / 98 + 20%6 / 30
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/mod.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/mod.rs.html new file mode 100644 index 0000000000..a1274fa791 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/mod.rs.html @@ -0,0 +1,3657 @@ + + + + + Grcov report - mod.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
pub use linkme::distributed_slice;
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
/// This procedural macro registers a decorated function with `conjure_rules`' global registry, and
+
+
+
+ 4 +
+
+ +
+
+
/// adds the rule to one or more `RuleSet`'s.
+
+
+
+ 5 +
+
+ +
+
+
///
+
+
+
+ 6 +
+
+ +
+
+
/// It may be used in any downstream crate.
+
+
+
+ 7 +
+
+ +
+
+
/// For more information on linker magic, see the [`linkme`](https://docs.rs/linkme/latest/linkme/) crate.
+
+
+
+ 8 +
+
+ +
+
+
///
+
+
+
+ 9 +
+
+ +
+
+
/// **IMPORTANT**: Since the resulting rule may not be explicitly referenced, it may be removed by the compiler's dead code elimination.
+
+
+
+ 10 +
+
+ +
+
+
/// To prevent this, you must ensure that either:
+
+
+
+ 11 +
+
+ +
+
+
/// 1. codegen-units is set to 1, i.e. in Cargo.toml:
+
+
+
+ 12 +
+
+ +
+
+
/// ```toml
+
+
+
+ 13 +
+
+ +
+
+
/// [profile.release]
+
+
+
+ 14 +
+
+ +
+
+
/// codegen-units = 1
+
+
+
+ 15 +
+
+ +
+
+
/// ```
+
+
+
+ 16 +
+
+ +
+
+
/// 2. The function is included somewhere else in the code
+
+
+
+ 17 +
+
+ +
+
+
///
+
+
+
+ 18 +
+
+ +
+
+
/// <hr>
+
+
+
+ 19 +
+
+ +
+
+
///
+
+
+
+ 20 +
+
+ +
+
+
/// Functions must have the signature `fn(&Expr) -> ApplicationResult`.
+
+
+
+ 21 +
+
+ +
+
+
/// The created rule will have the same name as the function.
+
+
+
+ 22 +
+
+ +
+
+
///
+
+
+
+ 23 +
+
+ +
+
+
/// Intermediary static variables are created to allow for the decentralized registry, with the prefix `CONJURE_GEN_`.
+
+
+
+ 24 +
+
+ +
+
+
/// Please ensure that other variable names in the same scope do not conflict with these.
+
+
+
+ 25 +
+
+ +
+
+
///
+
+
+
+ 26 +
+
+ +
+
+
/// This macro must decorate a function with the given signature.
+
+
+
+ 27 +
+
+ +
+
+
/// As arguments, it excepts a tuple of 2-tuples in the format:
+
+
+
+ 28 +
+
+ +
+
+
/// `((<RuleSet name>, <Priority in RuleSet>), ...)`
+
+
+
+ 29 +
+
+ +
+
+
///
+
+
+
+ 30 +
+
+ +
+
+
/// <hr>
+
+
+
+ 31 +
+
+ +
+
+
///
+
+
+
+ 32 +
+
+ +
+
+
/// For example:
+
+
+
+ 33 +
+
+ +
+
+
/// ```rust
+
+
+
+ 34 +
+
+ 1 +
+
+
/// use conjure_core::ast::Expression;
+
+
+
+ 35 +
+
+ 1 +
+
+
/// use conjure_core::model::Model;
+
+
+
+ 36 +
+
+ 1 +
+
+
/// use conjure_core::rule_engine::{ApplicationError, ApplicationResult, Reduction};
+
+
+
+ 37 +
+
+ 1 +
+
+
/// use conjure_core::rule_engine::register_rule;
+
+
+
+ 38 +
+
+ 1 +
+
+
///
+
+
+
+ 39 +
+
+ 1 +
+
+
/// #[register_rule(("RuleSetName", 10))]
+
+
+
+ 40 +
+
+ 1 +
+
+
/// fn identity(expr: &Expression, mdl: &Model) -> ApplicationResult {
+
+
+
+ 41 +
+
+ 1 +
+
+
///   Ok(Reduction::pure(expr.clone()))
+
+
+
+ 42 +
+
+ +
+
+
/// }
+
+
+
+ 43 +
+
+ +
+
+
/// ```
+
+
+
+ 44 +
+
+ 1 +
+
+
pub use conjure_rules_proc_macro::register_rule;
+
+
+
+ 45 +
+
+ +
+
+

+            
+
+
+ 46 +
+
+ +
+
+
/// This procedural macro registers a rule set with the global registry.
+
+
+
+ 47 +
+
+ +
+
+
/// It may be used in any downstream crate.
+
+
+
+ 48 +
+
+ +
+
+
///
+
+
+
+ 49 +
+
+ +
+
+
/// For more information on linker magic, see the [`linkme`](https://docs.rs/linkme/latest/linkme/) crate.
+
+
+
+ 50 +
+
+ +
+
+
///
+
+
+
+ 51 +
+
+ +
+
+
/// This macro uses the following syntax:
+
+
+
+ 52 +
+
+ +
+
+
///
+
+
+
+ 53 +
+
+ +
+
+
/// ```text
+
+
+
+ 54 +
+
+ +
+
+
/// register_rule_set!(<RuleSet name>, <RuleSet order>, (<DependencyRuleSet1>, <DependencyRuleSet2>, ...));
+
+
+
+ 55 +
+
+ +
+
+
/// ```
+
+
+
+ 56 +
+
+ +
+
+
///
+
+
+
+ 57 +
+
+ +
+
+
/// # Example
+
+
+
+ 58 +
+
+ +
+
+
///
+
+
+
+ 59 +
+
+ +
+
+
/// ```rust
+
+
+
+ 60 +
+
+ 1 +
+
+
/// use conjure_core::rule_engine::register_rule_set;
+
+
+
+ 61 +
+
+ 1 +
+
+
///
+
+
+
+ 62 +
+
+ 1 +
+
+
/// register_rule_set!("MyRuleSet", 10, ("DependencyRuleSet", "AnotherRuleSet"));
+
+
+
+ 63 +
+
+ 1 +
+
+
/// ```
+
+
+
+ 64 +
+
+ 1 +
+
+
#[doc(inline)]
+
+
+
+ 65 +
+
+ +
+
+
pub use conjure_rules_proc_macro::register_rule_set;
+
+
+
+ 66 +
+
+ +
+
+
pub use resolve_rules::{get_rule_priorities, get_rules_vec, resolve_rule_sets};
+
+
+
+ 67 +
+
+ +
+
+
pub use rewrite::{rewrite_model, RewriteError};
+
+
+
+ 68 +
+
+ +
+
+
pub use rule::{ApplicationError, ApplicationResult, Reduction, Rule};
+
+
+
+ 69 +
+
+ +
+
+
pub use rule_set::RuleSet;
+
+
+
+ 70 +
+
+ +
+
+

+            
+
+
+ 71 +
+
+ +
+
+
use crate::solver::SolverFamily;
+
+
+
+ 72 +
+
+ +
+
+

+            
+
+
+ 73 +
+
+ +
+
+
mod resolve_rules;
+
+
+
+ 74 +
+
+ +
+
+
mod rewrite;
+
+
+
+ 75 +
+
+ +
+
+
mod rule;
+
+
+
+ 76 +
+
+ +
+
+
mod rule_set;
+
+
+
+ 77 +
+
+ +
+
+

+            
+
+
+ 78 +
+
+ +
+
+
#[doc(hidden)]
+
+
+
+ 79 +
+
+ +
+
+
#[distributed_slice]
+
+
+
+ 80 +
+
+ +
+
+
pub static RULES_DISTRIBUTED_SLICE: [Rule<'static>];
+
+
+
+ 81 +
+
+ +
+
+

+            
+
+
+ 82 +
+
+ +
+
+
#[doc(hidden)]
+
+
+
+ 83 +
+
+ +
+
+
#[distributed_slice]
+
+
+
+ 84 +
+
+ +
+
+
pub static RULE_SETS_DISTRIBUTED_SLICE: [RuleSet<'static>];
+
+
+
+ 85 +
+
+ +
+
+

+            
+
+
+ 86 +
+
+ +
+
+
pub mod _dependencies {
+
+
+
+ 87 +
+
+ +
+
+
    pub use linkme;
+
+
+
+ 88 +
+
+ +
+
+
    pub use linkme::distributed_slice;
+
+
+
+ 89 +
+
+ +
+
+
}
+
+
+
+ 90 +
+
+ +
+
+

+            
+
+
+ 91 +
+
+ +
+
+
/// Returns a copied `Vec` of all rules registered with the `register_rule` macro.
+
+
+
+ 92 +
+
+ +
+
+
///
+
+
+
+ 93 +
+
+ +
+
+
/// Rules are not guaranteed to be in any particular order.
+
+
+
+ 94 +
+
+ +
+
+
///
+
+
+
+ 95 +
+
+ +
+
+
/// # Example
+
+
+
+ 96 +
+
+ +
+
+
/// ```rust
+
+
+
+ 97 +
+
+ +
+
+
/// # use conjure_core::rule_engine::{ApplicationResult, Reduction, get_rules};
+
+
+
+ 98 +
+
+ +
+
+
/// # use conjure_core::ast::Expression;
+
+
+
+ 99 +
+
+ +
+
+
/// # use conjure_core::model::Model;
+
+
+
+ 100 +
+
+ +
+
+
/// # use conjure_core::rule_engine::register_rule;
+
+
+
+ 101 +
+
+ +
+
+
///
+
+
+
+ 102 +
+
+ +
+
+
/// #[register_rule]
+
+
+
+ 103 +
+
+ +
+
+
/// fn identity(expr: &Expression, mdl: &Model) -> ApplicationResult {
+
+
+
+ 104 +
+
+ +
+
+
///   Ok(Reduction::pure(expr.clone()))
+
+
+
+ 105 +
+
+ +
+
+
/// }
+
+
+
+ 106 +
+
+ +
+
+
///
+
+
+
+ 107 +
+
+ +
+
+
/// fn main() {
+
+
+
+ 108 +
+
+ 1 +
+
+
///   println!("Rules: {:?}", get_rules());
+
+
+
+ 109 +
+
+ 1 +
+
+
/// }
+
+
+
+ 110 +
+
+ 1 +
+
+
/// ```
+
+
+
+ 111 +
+
+ +
+
+
///
+
+
+
+ 112 +
+
+ +
+
+
/// This will print (if no other rules are registered):
+
+
+
+ 113 +
+
+ +
+
+
/// ```text
+
+
+
+ 114 +
+
+ +
+
+
///   Rules: [Rule { name: "identity", application: MEM }]
+
+
+
+ 115 +
+
+ +
+
+
/// ```
+
+
+
+ 116 +
+
+ +
+
+
/// Where `MEM` is the memory address of the `identity` function.
+
+
+
+ 117 +
+
+ 615 +
+
+
pub fn get_rules() -> Vec<&'static Rule<'static>> {
+
+
+
+ 118 +
+
+ 615 +
+
+
    RULES_DISTRIBUTED_SLICE.iter().collect()
+
+
+
+ 119 +
+
+ 615 +
+
+
}
+
+
+
+ 120 +
+
+ +
+
+

+            
+
+
+ 121 +
+
+ +
+
+
/// Get a rule by name.
+
+
+
+ 122 +
+
+ +
+
+
/// Returns the rule with the given name or None if it doesn't exist.
+
+
+
+ 123 +
+
+ +
+
+
///
+
+
+
+ 124 +
+
+ +
+
+
/// # Example
+
+
+
+ 125 +
+
+ +
+
+
/// ```rust
+
+
+
+ 126 +
+
+ +
+
+
/// use conjure_core::rule_engine::register_rule;
+
+
+
+ 127 +
+
+ +
+
+
/// use conjure_core::rule_engine::{Rule, ApplicationResult, Reduction, get_rule_by_name};
+
+
+
+ 128 +
+
+ +
+
+
/// use conjure_core::ast::Expression;
+
+
+
+ 129 +
+
+ +
+
+
/// use conjure_core::model::Model;
+
+
+
+ 130 +
+
+ +
+
+
///
+
+
+
+ 131 +
+
+ +
+
+
/// #[register_rule]
+
+
+
+ 132 +
+
+ +
+
+
/// fn identity(expr: &Expression, mdl: &Model) -> ApplicationResult {
+
+
+
+ 133 +
+
+ +
+
+
///  Ok(Reduction::pure(expr.clone()))
+
+
+
+ 134 +
+
+ +
+
+
/// }
+
+
+
+ 135 +
+
+ +
+
+
///
+
+
+
+ 136 +
+
+ +
+
+
/// fn main() {
+
+
+
+ 137 +
+
+ 1 +
+
+
/// println!("Rule: {:?}", get_rule_by_name("identity"));
+
+
+
+ 138 +
+
+ 1 +
+
+
/// }
+
+
+
+ 139 +
+
+ 1 +
+
+
/// ```
+
+
+
+ 140 +
+
+ +
+
+
///
+
+
+
+ 141 +
+
+ +
+
+
/// This will print:
+
+
+
+ 142 +
+
+ +
+
+
/// ```text
+
+
+
+ 143 +
+
+ +
+
+
/// Rule: Some(Rule { name: "identity", application: MEM })
+
+
+
+ 144 +
+
+ +
+
+
/// ```
+
+
+
+ 145 +
+
+ 375 +
+
+
pub fn get_rule_by_name(name: &str) -> Option<&'static Rule<'static>> {
+
+
+
+ 146 +
+
+ 6570 +
+
+
    get_rules().iter().find(|rule| rule.name == name).cloned()
+
+
+
+ 147 +
+
+ 375 +
+
+
}
+
+
+
+ 148 +
+
+ +
+
+

+            
+
+
+ 149 +
+
+ +
+
+
/// Get all rule sets
+
+
+
+ 150 +
+
+ +
+
+
/// Returns a `Vec` of static references to all rule sets registered with the `register_rule_set` macro.
+
+
+
+ 151 +
+
+ +
+
+
/// Rule sets are not guaranteed to be in any particular order.
+
+
+
+ 152 +
+
+ +
+
+
///
+
+
+
+ 153 +
+
+ +
+
+
/// # Example
+
+
+
+ 154 +
+
+ +
+
+
/// ```rust
+
+
+
+ 155 +
+
+ 1 +
+
+
/// use conjure_core::rule_engine::register_rule_set;
+
+
+
+ 156 +
+
+ 1 +
+
+
/// use conjure_core::rule_engine::get_rule_sets;
+
+
+
+ 157 +
+
+ 1 +
+
+
///
+
+
+
+ 158 +
+
+ 1 +
+
+
/// register_rule_set!("MyRuleSet", 10, ("AnotherRuleSet"));
+
+
+
+ 159 +
+
+ 1 +
+
+
/// register_rule_set!("AnotherRuleSet", 5, ());
+
+
+
+ 160 +
+
+ 1 +
+
+
///
+
+
+
+ 161 +
+
+ 1 +
+
+
/// println!("Rule sets: {:?}", get_rule_sets());
+
+
+
+ 162 +
+
+ 1 +
+
+
/// ```
+
+
+
+ 163 +
+
+ 1 +
+
+
///
+
+
+
+ 164 +
+
+ +
+
+
/// This will print (if no other rule sets are registered):
+
+
+
+ 165 +
+
+ +
+
+
/// ```text
+
+
+
+ 166 +
+
+ +
+
+
/// Rule sets: [
+
+
+
+ 167 +
+
+ +
+
+
///   RuleSet { name: "MyRuleSet", order: 10, rules: OnceLock { state: Uninitialized }, dependencies: ["AnotherRuleSet"] },
+
+
+
+ 168 +
+
+ +
+
+
///   RuleSet { name: "AnotherRuleSet", order: 5, rules: OnceLock { state: Uninitialized }, dependencies: [] }
+
+
+
+ 169 +
+
+ +
+
+
/// ]
+
+
+
+ 170 +
+
+ +
+
+
/// ```
+
+
+
+ 171 +
+
+ +
+
+
///
+
+
+
+ 172 +
+
+ 465 +
+
+
pub fn get_rule_sets() -> Vec<&'static RuleSet<'static>> {
+
+
+
+ 173 +
+
+ 465 +
+
+
    RULE_SETS_DISTRIBUTED_SLICE.iter().collect()
+
+
+
+ 174 +
+
+ 465 +
+
+
}
+
+
+
+ 175 +
+
+ +
+
+

+            
+
+
+ 176 +
+
+ +
+
+
/// Get a rule set by name.
+
+
+
+ 177 +
+
+ +
+
+
/// Returns the rule set with the given name or None if it doesn't exist.
+
+
+
+ 178 +
+
+ +
+
+
///
+
+
+
+ 179 +
+
+ +
+
+
/// # Example
+
+
+
+ 180 +
+
+ +
+
+
/// ```rust
+
+
+
+ 181 +
+
+ 1 +
+
+
/// use conjure_core::rule_engine::register_rule_set;
+
+
+
+ 182 +
+
+ 1 +
+
+
/// use conjure_core::rule_engine::get_rule_set_by_name;
+
+
+
+ 183 +
+
+ 1 +
+
+
///
+
+
+
+ 184 +
+
+ 1 +
+
+
/// register_rule_set!("MyRuleSet", 10, ("DependencyRuleSet", "AnotherRuleSet"));
+
+
+
+ 185 +
+
+ 1 +
+
+
///
+
+
+
+ 186 +
+
+ 1 +
+
+
/// println!("Rule set: {:?}", get_rule_set_by_name("MyRuleSet"));
+
+
+
+ 187 +
+
+ 1 +
+
+
/// ```
+
+
+
+ 188 +
+
+ 1 +
+
+
///
+
+
+
+ 189 +
+
+ +
+
+
/// This will print:
+
+
+
+ 190 +
+
+ +
+
+
/// ```text
+
+
+
+ 191 +
+
+ +
+
+
/// Rule set: Some(RuleSet { name: "MyRuleSet", order: 10, rules: OnceLock { state: Uninitialized }, dependencies: ["DependencyRuleSet", "AnotherRuleSet"] })
+
+
+
+ 192 +
+
+ +
+
+
/// ```
+
+
+
+ 193 +
+
+ 255 +
+
+
pub fn get_rule_set_by_name(name: &str) -> Option<&'static RuleSet<'static>> {
+
+
+
+ 194 +
+
+ 255 +
+
+
    get_rule_sets()
+
+
+
+ 195 +
+
+ 255 +
+
+
        .iter()
+
+
+
+ 196 +
+
+ 615 +
+
+
        .find(|rule_set| rule_set.name == name)
+
+
+
+ 197 +
+
+ 255 +
+
+
        .cloned()
+
+
+
+ 198 +
+
+ 255 +
+
+
}
+
+
+
+ 199 +
+
+ +
+
+

+            
+
+
+ 200 +
+
+ +
+
+
/// Get all rule sets for a given solver family.
+
+
+
+ 201 +
+
+ +
+
+
/// Returns a `Vec` of static references to all rule sets that are applicable to the given solver family.
+
+
+
+ 202 +
+
+ +
+
+
///
+
+
+
+ 203 +
+
+ +
+
+
/// # Example
+
+
+
+ 204 +
+
+ +
+
+
///
+
+
+
+ 205 +
+
+ +
+
+
/// ```rust
+
+
+
+ 206 +
+
+ 1 +
+
+
/// use conjure_core::solver::SolverFamily;
+
+
+
+ 207 +
+
+ 1 +
+
+
/// use conjure_core::rule_engine::get_rule_sets_for_solver_family;
+
+
+
+ 208 +
+
+ 1 +
+
+
///
+
+
+
+ 209 +
+
+ 1 +
+
+
/// let rule_sets = get_rule_sets_for_solver_family(SolverFamily::SAT);
+
+
+
+ 210 +
+
+ 1 +
+
+
/// assert_eq!(rule_sets.len(), 1);
+
+
+
+ 211 +
+
+ 1 +
+
+
/// assert_eq!(rule_sets[0].name, "CNF");
+
+
+
+ 212 +
+
+ 1 +
+
+
/// ```
+
+
+
+ 213 +
+
+ 183 +
+
+
pub fn get_rule_sets_for_solver_family(
+
+
+
+ 214 +
+
+ 195 +
+
+
    solver_family: SolverFamily,
+
+
+
+ 215 +
+
+ 195 +
+
+
) -> Vec<&'static RuleSet<'static>> {
+
+
+
+ 216 +
+
+ 195 +
+
+
    get_rule_sets()
+
+
+
+ 217 +
+
+ 195 +
+
+
        .iter()
+
+
+
+ 218 +
+
+ 780 +
+
+
        .filter(|rule_set| {
+
+
+
+ 219 +
+
+ 780 +
+
+
            rule_set
+
+
+
+ 220 +
+
+ 780 +
+
+
                .solver_families
+
+
+
+ 221 +
+
+ 780 +
+
+
                .iter()
+
+
+
+ 222 +
+
+ 780 +
+
+
                .any(|family| family.eq(&solver_family))
+
+
+
+ 223 +
+
+ 780 +
+
+
        })
+
+
+
+ 224 +
+
+ 195 +
+
+
        .cloned()
+
+
+
+ 225 +
+
+ 195 +
+
+
        .collect()
+
+
+
+ 226 +
+
+ 195 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/resolve_rules.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/resolve_rules.rs.html new file mode 100644 index 0000000000..6a067ced52 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/resolve_rules.rs.html @@ -0,0 +1,2505 @@ + + + + + Grcov report - resolve_rules.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use std::collections::{HashMap, HashSet};
+
+
+
+ 2 +
+
+ +
+
+
use std::fmt::Display;
+
+
+
+ 3 +
+
+ +
+
+

+            
+
+
+ 4 +
+
+ +
+
+
use thiserror::Error;
+
+
+
+ 5 +
+
+ +
+
+

+            
+
+
+ 6 +
+
+ +
+
+
use crate::rule_engine::{get_rule_set_by_name, get_rule_sets_for_solver_family, Rule, RuleSet};
+
+
+
+ 7 +
+
+ +
+
+
use crate::solver::SolverFamily;
+
+
+
+ 8 +
+
+ +
+
+

+            
+
+
+ 9 +
+
+ +
+
+
#[derive(Debug, Error)]
+
+
+
+ 10 +
+
+ +
+
+
pub enum ResolveRulesError {
+
+
+
+ 11 +
+
+ +
+
+
    RuleSetNotFound,
+
+
+
+ 12 +
+
+ +
+
+
}
+
+
+
+ 13 +
+
+ +
+
+

+            
+
+
+ 14 +
+
+ +
+
+
impl Display for ResolveRulesError {
+
+
+
+ 15 +
+
+ +
+
+
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+
+
+
+ 16 +
+
+ +
+
+
        match self {
+
+
+
+ 17 +
+
+ +
+
+
            ResolveRulesError::RuleSetNotFound => write!(f, "Rule set not found."),
+
+
+
+ 18 +
+
+ +
+
+
        }
+
+
+
+ 19 +
+
+ +
+
+
    }
+
+
+
+ 20 +
+
+ +
+
+
}
+
+
+
+ 21 +
+
+ +
+
+

+            
+
+
+ 22 +
+
+ +
+
+
/// Helper function to get a rule set by name, or return an error if it doesn't exist.
+
+
+
+ 23 +
+
+ +
+
+
///
+
+
+
+ 24 +
+
+ +
+
+
/// # Arguments
+
+
+
+ 25 +
+
+ +
+
+
/// - `rule_set_name` The name of the rule set to get.
+
+
+
+ 26 +
+
+ +
+
+
///
+
+
+
+ 27 +
+
+ +
+
+
/// # Returns
+
+
+
+ 28 +
+
+ +
+
+
/// - The rule set with the given name or `RuleSetError::RuleSetNotFound` if it doesn't exist.
+
+
+
+ 29 +
+
+ 180 +
+
+
fn get_rule_set(rule_set_name: &str) -> Result<&'static RuleSet<'static>, ResolveRulesError> {
+
+
+
+ 30 +
+
+ 180 +
+
+
    match get_rule_set_by_name(rule_set_name) {
+
+
+
+ 31 +
+
+ 180 +
+
+
        Some(rule_set) => Ok(rule_set),
+
+
+
+ 32 +
+
+ +
+
+
        None => Err(ResolveRulesError::RuleSetNotFound),
+
+
+
+ 33 +
+
+ +
+
+
    }
+
+
+
+ 34 +
+
+ 180 +
+
+
}
+
+
+
+ 35 +
+
+ +
+
+

+            
+
+
+ 36 +
+
+ +
+
+
/// Resolve a list of rule sets (and dependencies) by their names
+
+
+
+ 37 +
+
+ +
+
+
///
+
+
+
+ 38 +
+
+ +
+
+
/// # Arguments
+
+
+
+ 39 +
+
+ +
+
+
/// - `rule_set_names` The names of the rule sets to resolve.
+
+
+
+ 40 +
+
+ +
+
+
///
+
+
+
+ 41 +
+
+ +
+
+
/// # Returns
+
+
+
+ 42 +
+
+ +
+
+
/// - A list of the given rule sets and all of their dependencies, or error
+
+
+
+ 43 +
+
+ +
+
+
///
+
+
+
+ 44 +
+
+ +
+
+
#[allow(clippy::mutable_key_type)] // RuleSet is 'static so it's fine
+
+
+
+ 45 +
+
+ 180 +
+
+
pub fn rule_sets_by_names<'a>(
+
+
+
+ 46 +
+
+ 180 +
+
+
    rule_set_names: &Vec<&str>,
+
+
+
+ 47 +
+
+ 180 +
+
+
) -> Result<HashSet<&'a RuleSet<'static>>, ResolveRulesError> {
+
+
+
+ 48 +
+
+ 180 +
+
+
    let mut rs_set: HashSet<&'static RuleSet<'static>> = HashSet::new();
+
+
+
+ 49 +
+
+ +
+
+

+            
+
+
+ 50 +
+
+ 360 +
+
+
    for rule_set_name in rule_set_names {
+
+
+
+ 51 +
+
+ 180 +
+
+
        let rule_set = get_rule_set(rule_set_name)?;
+
+
+
+ 52 +
+
+ 180 +
+
+
        let new_dependencies = rule_set.get_dependencies();
+
+
+
+ 53 +
+
+ 180 +
+
+
        rs_set.insert(rule_set);
+
+
+
+ 54 +
+
+ 180 +
+
+
        rs_set.extend(new_dependencies);
+
+
+
+ 55 +
+
+ +
+
+
    }
+
+
+
+ 56 +
+
+ +
+
+

+            
+
+
+ 57 +
+
+ 180 +
+
+
    Ok(rs_set)
+
+
+
+ 58 +
+
+ 180 +
+
+
}
+
+
+
+ 59 +
+
+ +
+
+

+            
+
+
+ 60 +
+
+ +
+
+
/// Resolves the final set of rule sets to apply based on target solver and extra rule set names.
+
+
+
+ 61 +
+
+ +
+
+
///
+
+
+
+ 62 +
+
+ +
+
+
/// # Arguments
+
+
+
+ 63 +
+
+ +
+
+
/// - `target_solver` The solver to resolve the rule sets for.
+
+
+
+ 64 +
+
+ +
+
+
/// - `extra_rs_names` The names of the extra rule sets to use
+
+
+
+ 65 +
+
+ +
+
+
///
+
+
+
+ 66 +
+
+ +
+
+
/// # Returns
+
+
+
+ 67 +
+
+ +
+
+
/// - A vector of rule sets to apply.
+
+
+
+ 68 +
+
+ +
+
+
///
+
+
+
+ 69 +
+
+ +
+
+
#[allow(clippy::mutable_key_type)] // RuleSet is 'static so it's fine
+
+
+
+ 70 +
+
+ 180 +
+
+
pub fn resolve_rule_sets<'a>(
+
+
+
+ 71 +
+
+ 180 +
+
+
    target_solver: SolverFamily,
+
+
+
+ 72 +
+
+ 180 +
+
+
    extra_rs_names: &Vec<&str>,
+
+
+
+ 73 +
+
+ 180 +
+
+
) -> Result<Vec<&'a RuleSet<'static>>, ResolveRulesError> {
+
+
+
+ 74 +
+
+ 180 +
+
+
    let mut ans = HashSet::new();
+
+
+
+ 75 +
+
+ +
+
+

+            
+
+
+ 76 +
+
+ 180 +
+
+
    for rs in get_rule_sets_for_solver_family(target_solver) {
+
+
+
+ 77 +
+
+ 180 +
+
+
        ans.extend(rs.with_dependencies());
+
+
+
+ 78 +
+
+ 180 +
+
+
    }
+
+
+
+ 79 +
+
+ +
+
+

+            
+
+
+ 80 +
+
+ 180 +
+
+
    ans.extend(rule_sets_by_names(extra_rs_names)?);
+
+
+
+ 81 +
+
+ 180 +
+
+
    Ok(ans.iter().cloned().collect())
+
+
+
+ 82 +
+
+ 180 +
+
+
}
+
+
+
+ 83 +
+
+ +
+
+

+            
+
+
+ 84 +
+
+ +
+
+
/// Convert a list of rule sets into a final map of rules to their priorities.
+
+
+
+ 85 +
+
+ +
+
+
///
+
+
+
+ 86 +
+
+ +
+
+
/// # Arguments
+
+
+
+ 87 +
+
+ +
+
+
/// - `rule_sets` The rule sets to get the rules from.
+
+
+
+ 88 +
+
+ +
+
+
/// # Returns
+
+
+
+ 89 +
+
+ +
+
+
/// - A map of rules to their priorities.
+
+
+
+ 90 +
+
+ 165 +
+
+
pub fn get_rule_priorities<'a>(
+
+
+
+ 91 +
+
+ 165 +
+
+
    rule_sets: &Vec<&'a RuleSet<'a>>,
+
+
+
+ 92 +
+
+ 165 +
+
+
) -> Result<HashMap<&'a Rule<'a>, u8>, ResolveRulesError> {
+
+
+
+ 93 +
+
+ 165 +
+
+
    let mut rule_priorities: HashMap<&'a Rule<'a>, (&'a RuleSet<'a>, u8)> = HashMap::new();
+
+
+
+ 94 +
+
+ +
+
+

+            
+
+
+ 95 +
+
+ 660 +
+
+
    for rs in rule_sets {
+
+
+
+ 96 +
+
+ 4290 +
+
+
        for (rule, priority) in rs.get_rules() {
+
+
+
+ 97 +
+
+ 4290 +
+
+
            if let Some((old_rs, _)) = rule_priorities.get(rule) {
+
+
+
+ 98 +
+
+ +
+
+
                if rs.order >= old_rs.order {
+
+
+
+ 99 +
+
+ +
+
+
                    rule_priorities.insert(rule, (&rs, *priority));
+
+
+
+ 100 +
+
+ +
+
+
                }
+
+
+
+ 101 +
+
+ 4290 +
+
+
            } else {
+
+
+
+ 102 +
+
+ 4290 +
+
+
                rule_priorities.insert(rule, (&rs, *priority));
+
+
+
+ 103 +
+
+ 4290 +
+
+
            }
+
+
+
+ 104 +
+
+ +
+
+
        }
+
+
+
+ 105 +
+
+ +
+
+
    }
+
+
+
+ 106 +
+
+ +
+
+

+            
+
+
+ 107 +
+
+ 165 +
+
+
    let mut ans: HashMap<&'a Rule<'a>, u8> = HashMap::new();
+
+
+
+ 108 +
+
+ 4455 +
+
+
    for (rule, (_, priority)) in rule_priorities {
+
+
+
+ 109 +
+
+ 4290 +
+
+
        ans.insert(rule, priority);
+
+
+
+ 110 +
+
+ 4290 +
+
+
    }
+
+
+
+ 111 +
+
+ +
+
+

+            
+
+
+ 112 +
+
+ 165 +
+
+
    Ok(ans)
+
+
+
+ 113 +
+
+ 165 +
+
+
}
+
+
+
+ 114 +
+
+ +
+
+

+            
+
+
+ 115 +
+
+ +
+
+
/// Compare two rules by their priorities and names.
+
+
+
+ 116 +
+
+ +
+
+
///
+
+
+
+ 117 +
+
+ +
+
+
/// Takes the rules and a map of rules to their priorities.
+
+
+
+ 118 +
+
+ +
+
+
/// If rules are not in the map, they are assumed to have priority 0.
+
+
+
+ 119 +
+
+ +
+
+
/// If the rules have the same priority, they are compared by their names.
+
+
+
+ 120 +
+
+ +
+
+
///
+
+
+
+ 121 +
+
+ +
+
+
/// # Arguments
+
+
+
+ 122 +
+
+ +
+
+
/// - `a` first rule to compare.
+
+
+
+ 123 +
+
+ +
+
+
/// - `b` second rule to compare.
+
+
+
+ 124 +
+
+ +
+
+
/// - `rule_priorities` The priorities of the rules.
+
+
+
+ 125 +
+
+ +
+
+
///
+
+
+
+ 126 +
+
+ +
+
+
/// # Returns
+
+
+
+ 127 +
+
+ +
+
+
/// - The ordering of the two rules.
+
+
+
+ 128 +
+
+ 19035 +
+
+
pub fn rule_cmp<'a>(
+
+
+
+ 129 +
+
+ 19035 +
+
+
    a: &Rule<'a>,
+
+
+
+ 130 +
+
+ 19035 +
+
+
    b: &Rule<'a>,
+
+
+
+ 131 +
+
+ 19035 +
+
+
    rule_priorities: &HashMap<&'a Rule<'a>, u8>,
+
+
+
+ 132 +
+
+ 19035 +
+
+
) -> std::cmp::Ordering {
+
+
+
+ 133 +
+
+ 19035 +
+
+
    let a_priority = *rule_priorities.get(a).unwrap_or(&0);
+
+
+
+ 134 +
+
+ 19035 +
+
+
    let b_priority = *rule_priorities.get(b).unwrap_or(&0);
+
+
+
+ 135 +
+
+ 19035 +
+
+

+            
+
+
+ 136 +
+
+ 19035 +
+
+
    if a_priority == b_priority {
+
+
+
+ 137 +
+
+ 16755 +
+
+
        return a.name.cmp(b.name);
+
+
+
+ 138 +
+
+ 2280 +
+
+
    }
+
+
+
+ 139 +
+
+ 2280 +
+
+

+            
+
+
+ 140 +
+
+ 2280 +
+
+
    b_priority.cmp(&a_priority)
+
+
+
+ 141 +
+
+ 19035 +
+
+
}
+
+
+
+ 142 +
+
+ +
+
+

+            
+
+
+ 143 +
+
+ +
+
+
/// Get a final ordering of rules based on their priorities and names.
+
+
+
+ 144 +
+
+ +
+
+
///
+
+
+
+ 145 +
+
+ +
+
+
/// # Arguments
+
+
+
+ 146 +
+
+ +
+
+
/// - `rule_priorities` The priorities of the rules.
+
+
+
+ 147 +
+
+ +
+
+
///
+
+
+
+ 148 +
+
+ +
+
+
/// # Returns
+
+
+
+ 149 +
+
+ +
+
+
/// - A list of rules sorted by their priorities and names.
+
+
+
+ 150 +
+
+ 165 +
+
+
pub fn get_rules_vec<'a>(rule_priorities: &HashMap<&'a Rule<'a>, u8>) -> Vec<&'a Rule<'a>> {
+
+
+
+ 151 +
+
+ 165 +
+
+
    let mut rules: Vec<&'a Rule<'a>> = rule_priorities.keys().copied().collect();
+
+
+
+ 152 +
+
+ 19035 +
+
+
    rules.sort_by(|a, b| rule_cmp(a, b, rule_priorities));
+
+
+
+ 153 +
+
+ 165 +
+
+
    rules
+
+
+
+ 154 +
+
+ 165 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/rewrite.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/rewrite.rs.html new file mode 100644 index 0000000000..53cdfe844f --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/rewrite.rs.html @@ -0,0 +1,2009 @@ + + + + + Grcov report - rewrite.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use std::fmt::Display;
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
use thiserror::Error;
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ +
+
+
use uniplate::uniplate::Uniplate;
+
+
+
+ 6 +
+
+ +
+
+

+            
+
+
+ 7 +
+
+ +
+
+
use crate::rule_engine::{Reduction, Rule, RuleSet};
+
+
+
+ 8 +
+
+ +
+
+
use crate::{
+
+
+
+ 9 +
+
+ +
+
+
    ast::Expression,
+
+
+
+ 10 +
+
+ +
+
+
    rule_engine::resolve_rules::{
+
+
+
+ 11 +
+
+ +
+
+
        get_rule_priorities, get_rules_vec, ResolveRulesError as ResolveError,
+
+
+
+ 12 +
+
+ +
+
+
    },
+
+
+
+ 13 +
+
+ +
+
+
    Model,
+
+
+
+ 14 +
+
+ +
+
+
};
+
+
+
+ 15 +
+
+ +
+
+

+            
+
+
+ 16 +
+
+ +
+
+
#[derive(Debug)]
+
+
+
+ 17 +
+
+ +
+
+
struct RuleResult<'a> {
+
+
+
+ 18 +
+
+ +
+
+
    rule: &'a Rule<'a>,
+
+
+
+ 19 +
+
+ +
+
+
    reduction: Reduction,
+
+
+
+ 20 +
+
+ +
+
+
}
+
+
+
+ 21 +
+
+ +
+
+

+            
+
+
+ 22 +
+
+ +
+
+
#[derive(Debug, Error)]
+
+
+
+ 23 +
+
+ +
+
+
pub enum RewriteError {
+
+
+
+ 24 +
+
+ +
+
+
    ResolveRulesError(ResolveError),
+
+
+
+ 25 +
+
+ +
+
+
}
+
+
+
+ 26 +
+
+ +
+
+

+            
+
+
+ 27 +
+
+ +
+
+
impl Display for RewriteError {
+
+
+
+ 28 +
+
+ +
+
+
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+
+
+
+ 29 +
+
+ +
+
+
        match self {
+
+
+
+ 30 +
+
+ +
+
+
            RewriteError::ResolveRulesError(e) => write!(f, "Error resolving rules: {}", e),
+
+
+
+ 31 +
+
+ +
+
+
        }
+
+
+
+ 32 +
+
+ +
+
+
    }
+
+
+
+ 33 +
+
+ +
+
+
}
+
+
+
+ 34 +
+
+ +
+
+

+            
+
+
+ 35 +
+
+ +
+
+
impl From<ResolveError> for RewriteError {
+
+
+
+ 36 +
+
+ +
+
+
    fn from(error: ResolveError) -> Self {
+
+
+
+ 37 +
+
+ +
+
+
        RewriteError::ResolveRulesError(error)
+
+
+
+ 38 +
+
+ +
+
+
    }
+
+
+
+ 39 +
+
+ +
+
+
}
+
+
+
+ 40 +
+
+ +
+
+

+            
+
+
+ 41 +
+
+ +
+
+
/// Rewrites the model by applying the rules to all constraints.
+
+
+
+ 42 +
+
+ +
+
+
///
+
+
+
+ 43 +
+
+ +
+
+
/// Any side-effects such as symbol table updates and top-level constraints are applied to the returned model.
+
+
+
+ 44 +
+
+ +
+
+
///
+
+
+
+ 45 +
+
+ +
+
+
/// # Returns
+
+
+
+ 46 +
+
+ +
+
+
/// A copy of the model after all, if any, possible rules are applied to its constraints.
+
+
+
+ 47 +
+
+ 165 +
+
+
pub fn rewrite_model<'a>(
+
+
+
+ 48 +
+
+ 165 +
+
+
    model: &Model,
+
+
+
+ 49 +
+
+ 165 +
+
+
    rule_sets: &Vec<&'a RuleSet<'a>>,
+
+
+
+ 50 +
+
+ 165 +
+
+
) -> Result<Model, RewriteError> {
+
+
+
+ 51 +
+
+ 165 +
+
+
    let rule_priorities = get_rule_priorities(rule_sets)?;
+
+
+
+ 52 +
+
+ 165 +
+
+
    let rules = get_rules_vec(&rule_priorities);
+
+
+
+ 53 +
+
+ 165 +
+
+
    let mut new_model = model.clone();
+
+
+
+ 54 +
+
+ +
+
+

+            
+
+
+ 55 +
+
+ 1755 +
+
+
    while let Some(step) = rewrite_iteration(&new_model.constraints, &new_model, &rules) {
+
+
+
+ 56 +
+
+ 1590 +
+
+
        step.apply(&mut new_model); // Apply side-effects (e.g. symbol table updates)
+
+
+
+ 57 +
+
+ 1590 +
+
+
    }
+
+
+
+ 58 +
+
+ 165 +
+
+
    Ok(new_model)
+
+
+
+ 59 +
+
+ 165 +
+
+
}
+
+
+
+ 60 +
+
+ +
+
+

+            
+
+
+ 61 +
+
+ +
+
+
/// # Returns
+
+
+
+ 62 +
+
+ +
+
+
/// - Some(<new_expression>) after applying the first applicable rule to `expr` or a sub-expression.
+
+
+
+ 63 +
+
+ +
+
+
/// - None if no rule is applicable to the expression or any sub-expression.
+
+
+
+ 64 +
+
+ 29385 +
+
+
fn rewrite_iteration<'a>(
+
+
+
+ 65 +
+
+ 29385 +
+
+
    expression: &'a Expression,
+
+
+
+ 66 +
+
+ 29385 +
+
+
    model: &'a Model,
+
+
+
+ 67 +
+
+ 29385 +
+
+
    rules: &'a Vec<&'a Rule<'a>>,
+
+
+
+ 68 +
+
+ 29385 +
+
+
) -> Option<Reduction> {
+
+
+
+ 69 +
+
+ 29385 +
+
+
    let rule_results = apply_all_rules(expression, model, rules);
+
+
+
+ 70 +
+
+ 29385 +
+
+
    if let Some(new) = choose_rewrite(&rule_results) {
+
+
+
+ 71 +
+
+ 1590 +
+
+
        return Some(new);
+
+
+
+ 72 +
+
+ +
+
+
    } else {
+
+
+
+ 73 +
+
+ 27795 +
+
+
        let mut sub = expression.children();
+
+
+
+ 74 +
+
+ +
+
+

+            
+
+
+ 75 +
+
+ 27795 +
+
+
        for i in 0..sub.len() {
+
+
+
+ 76 +
+
+ 27630 +
+
+
            if let Some(red) = rewrite_iteration(&sub[i], model, rules) {
+
+
+
+ 77 +
+
+ 1770 +
+
+
                sub[i] = red.new_expression;
+
+
+
+ 78 +
+
+ 1770 +
+
+
                if let Ok(res) = expression.with_children(sub.clone()) {
+
+
+
+ 79 +
+
+ 1770 +
+
+
                    return Some(Reduction::new(res, red.new_top, red.symbols));
+
+
+
+ 80 +
+
+ +
+
+
                }
+
+
+
+ 81 +
+
+ 25860 +
+
+
            }
+
+
+
+ 82 +
+
+ +
+
+
        }
+
+
+
+ 83 +
+
+ +
+
+
    }
+
+
+
+ 84 +
+
+ 26025 +
+
+
    None // No rules applicable to this branch of the expression
+
+
+
+ 85 +
+
+ 29385 +
+
+
}
+
+
+
+ 86 +
+
+ +
+
+

+            
+
+
+ 87 +
+
+ +
+
+
/// # Returns
+
+
+
+ 88 +
+
+ +
+
+
/// - A list of RuleResults after applying all rules to `expression`.
+
+
+
+ 89 +
+
+ +
+
+
/// - An empty list if no rules are applicable.
+
+
+
+ 90 +
+
+ 29385 +
+
+
fn apply_all_rules<'a>(
+
+
+
+ 91 +
+
+ 29385 +
+
+
    expression: &'a Expression,
+
+
+
+ 92 +
+
+ 29385 +
+
+
    model: &'a Model,
+
+
+
+ 93 +
+
+ 29385 +
+
+
    rules: &'a Vec<&'a Rule<'a>>,
+
+
+
+ 94 +
+
+ 29385 +
+
+
) -> Vec<RuleResult<'a>> {
+
+
+
+ 95 +
+
+ 29385 +
+
+
    let mut results = Vec::new();
+
+
+
+ 96 +
+
+ 793395 +
+
+
    for rule in rules {
+
+
+
+ 97 +
+
+ 764010 +
+
+
        match rule.apply(expression, model) {
+
+
+
+ 98 +
+
+ 1620 +
+
+
            Ok(red) => {
+
+
+
+ 99 +
+
+ 1620 +
+
+
                results.push(RuleResult {
+
+
+
+ 100 +
+
+ 1620 +
+
+
                    rule,
+
+
+
+ 101 +
+
+ 1620 +
+
+
                    reduction: red,
+
+
+
+ 102 +
+
+ 1620 +
+
+
                });
+
+
+
+ 103 +
+
+ 1620 +
+
+
                log::trace!(target: "file", "Rule applied: {:?}", rule);
+
+
+
+ 104 +
+
+ +
+
+
            }
+
+
+
+ 105 +
+
+ +
+
+
            Err(_) => {
+
+
+
+ 106 +
+
+ 762390 +
+
+
                log::trace!(target: "file", "Rule attempted but not applied: {:?}", rule);
+
+
+
+ 107 +
+
+ 762390 +
+
+
                continue;
+
+
+
+ 108 +
+
+ +
+
+
            }
+
+
+
+ 109 +
+
+ +
+
+
        }
+
+
+
+ 110 +
+
+ +
+
+
    }
+
+
+
+ 111 +
+
+ 29385 +
+
+
    results
+
+
+
+ 112 +
+
+ 29385 +
+
+
}
+
+
+
+ 113 +
+
+ +
+
+

+            
+
+
+ 114 +
+
+ +
+
+
/// # Returns
+
+
+
+ 115 +
+
+ +
+
+
/// - Some(<reduction>) after applying the first rule in `results`.
+
+
+
+ 116 +
+
+ +
+
+
/// - None if `results` is empty.
+
+
+
+ 117 +
+
+ 29385 +
+
+
fn choose_rewrite(results: &[RuleResult]) -> Option<Reduction> {
+
+
+
+ 118 +
+
+ 29385 +
+
+
    if results.is_empty() {
+
+
+
+ 119 +
+
+ 27795 +
+
+
        return None;
+
+
+
+ 120 +
+
+ 1590 +
+
+
    }
+
+
+
+ 121 +
+
+ 1590 +
+
+
    // Return the first result for now
+
+
+
+ 122 +
+
+ 1590 +
+
+
    Some(results[0].reduction.clone())
+
+
+
+ 123 +
+
+ 29385 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/rule.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/rule.rs.html new file mode 100644 index 0000000000..49144b752f --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/rule.rs.html @@ -0,0 +1,2313 @@ + + + + + Grcov report - rule.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use std::fmt::{self, Display, Formatter};
+
+
+
+ 2 +
+
+ +
+
+
use std::hash::Hash;
+
+
+
+ 3 +
+
+ +
+
+

+            
+
+
+ 4 +
+
+ +
+
+
use thiserror::Error;
+
+
+
+ 5 +
+
+ +
+
+

+            
+
+
+ 6 +
+
+ +
+
+
use crate::ast::{Expression, SymbolTable};
+
+
+
+ 7 +
+
+ +
+
+
use crate::metadata::Metadata;
+
+
+
+ 8 +
+
+ +
+
+
use crate::model::Model;
+
+
+
+ 9 +
+
+ +
+
+

+            
+
+
+ 10 +
+
+ +
+
+
#[derive(Debug, Error)]
+
+
+
+ 11 +
+
+ +
+
+
pub enum ApplicationError {
+
+
+
+ 12 +
+
+ +
+
+
    #[error("Rule is not applicable")]
+
+
+
+ 13 +
+
+ +
+
+
    RuleNotApplicable,
+
+
+
+ 14 +
+
+ +
+
+

+            
+
+
+ 15 +
+
+ +
+
+
    #[error("Could not find the min/max bounds for the expression")]
+
+
+
+ 16 +
+
+ +
+
+
    BoundError,
+
+
+
+ 17 +
+
+ +
+
+
}
+
+
+
+ 18 +
+
+ +
+
+

+            
+
+
+ 19 +
+
+ +
+
+
/// The result of applying a rule to an expression.
+
+
+
+ 20 +
+
+ +
+
+
///
+
+
+
+ 21 +
+
+ +
+
+
/// Contains an expression to replace the original, a top-level constraint to add to the top of the constraint AST, and an expansion to the model symbol table.
+
+
+
+ 22 +
+
+ +
+
+
#[non_exhaustive]
+
+
+
+ 23 +
+
+ +
+
+
#[derive(Clone, Debug)]
+
+
+
+ 24 +
+
+ +
+
+
pub struct Reduction {
+
+
+
+ 25 +
+
+ +
+
+
    pub new_expression: Expression,
+
+
+
+ 26 +
+
+ +
+
+
    pub new_top: Expression,
+
+
+
+ 27 +
+
+ +
+
+
    pub symbols: SymbolTable,
+
+
+
+ 28 +
+
+ +
+
+
}
+
+
+
+ 29 +
+
+ +
+
+

+            
+
+
+ 30 +
+
+ +
+
+
/// The result of applying a rule to an expression.
+
+
+
+ 31 +
+
+ +
+
+
/// Contains either a set of reduction instructions or an error.
+
+
+
+ 32 +
+
+ +
+
+
pub type ApplicationResult = Result<Reduction, ApplicationError>;
+
+
+
+ 33 +
+
+ +
+
+

+            
+
+
+ 34 +
+
+ +
+
+
impl Reduction {
+
+
+
+ 35 +
+
+ 1845 +
+
+
    pub fn new(new_expression: Expression, new_top: Expression, symbols: SymbolTable) -> Self {
+
+
+
+ 36 +
+
+ 1845 +
+
+
        Self {
+
+
+
+ 37 +
+
+ 1845 +
+
+
            new_expression,
+
+
+
+ 38 +
+
+ 1845 +
+
+
            new_top,
+
+
+
+ 39 +
+
+ 1845 +
+
+
            symbols,
+
+
+
+ 40 +
+
+ 1845 +
+
+
        }
+
+
+
+ 41 +
+
+ 1845 +
+
+
    }
+
+
+
+ 42 +
+
+ +
+
+

+            
+
+
+ 43 +
+
+ +
+
+
    /// Represents a reduction with no side effects on the model.
+
+
+
+ 44 +
+
+ 1815 +
+
+
    pub fn pure(new_expression: Expression) -> Self {
+
+
+
+ 45 +
+
+ 1815 +
+
+
        Self {
+
+
+
+ 46 +
+
+ 1815 +
+
+
            new_expression,
+
+
+
+ 47 +
+
+ 1815 +
+
+
            new_top: Expression::Nothing,
+
+
+
+ 48 +
+
+ 1815 +
+
+
            symbols: SymbolTable::new(),
+
+
+
+ 49 +
+
+ 1815 +
+
+
        }
+
+
+
+ 50 +
+
+ 1815 +
+
+
    }
+
+
+
+ 51 +
+
+ +
+
+

+            
+
+
+ 52 +
+
+ +
+
+
    /// Represents a reduction that also modifies the symbol table.
+
+
+
+ 53 +
+
+ +
+
+
    pub fn with_symbols(new_expression: Expression, symbols: SymbolTable) -> Self {
+
+
+
+ 54 +
+
+ +
+
+
        Self {
+
+
+
+ 55 +
+
+ +
+
+
            new_expression,
+
+
+
+ 56 +
+
+ +
+
+
            new_top: Expression::Nothing,
+
+
+
+ 57 +
+
+ +
+
+
            symbols,
+
+
+
+ 58 +
+
+ +
+
+
        }
+
+
+
+ 59 +
+
+ +
+
+
    }
+
+
+
+ 60 +
+
+ +
+
+

+            
+
+
+ 61 +
+
+ +
+
+
    /// Represents a reduction that also adds a top-level constraint to the model.
+
+
+
+ 62 +
+
+ +
+
+
    pub fn with_top(new_expression: Expression, new_top: Expression) -> Self {
+
+
+
+ 63 +
+
+ +
+
+
        Self {
+
+
+
+ 64 +
+
+ +
+
+
            new_expression,
+
+
+
+ 65 +
+
+ +
+
+
            new_top,
+
+
+
+ 66 +
+
+ +
+
+
            symbols: SymbolTable::new(),
+
+
+
+ 67 +
+
+ +
+
+
        }
+
+
+
+ 68 +
+
+ +
+
+
    }
+
+
+
+ 69 +
+
+ +
+
+

+            
+
+
+ 70 +
+
+ +
+
+
    // Apply side-effects (e.g. symbol table updates
+
+
+
+ 71 +
+
+ 1590 +
+
+
    pub fn apply(self, model: &mut Model) {
+
+
+
+ 72 +
+
+ 1590 +
+
+
        model.variables.extend(self.symbols); // Add new assignments to the symbol table
+
+
+
+ 73 +
+
+ 1590 +
+
+
        if self.new_top.is_nothing() {
+
+
+
+ 74 +
+
+ 1515 +
+
+
            model.constraints = self.new_expression.clone();
+
+
+
+ 75 +
+
+ 1515 +
+
+
        } else {
+
+
+
+ 76 +
+
+ 75 +
+
+
            model.constraints = match self.new_expression {
+
+
+
+ 77 +
+
+ +
+
+
                Expression::And(metadata, mut exprs) => {
+
+
+
+ 78 +
+
+ +
+
+
                    // Avoid creating a nested conjunction
+
+
+
+ 79 +
+
+ +
+
+
                    exprs.push(self.new_top.clone());
+
+
+
+ 80 +
+
+ +
+
+
                    Expression::And(metadata.clone(), exprs)
+
+
+
+ 81 +
+
+ +
+
+
                }
+
+
+
+ 82 +
+
+ 75 +
+
+
                _ => Expression::And(
+
+
+
+ 83 +
+
+ 75 +
+
+
                    Metadata::new(),
+
+
+
+ 84 +
+
+ 75 +
+
+
                    vec![self.new_expression.clone(), self.new_top],
+
+
+
+ 85 +
+
+ 75 +
+
+
                ),
+
+
+
+ 86 +
+
+ +
+
+
            };
+
+
+
+ 87 +
+
+ +
+
+
        }
+
+
+
+ 88 +
+
+ 1590 +
+
+
    }
+
+
+
+ 89 +
+
+ +
+
+
}
+
+
+
+ 90 +
+
+ +
+
+

+            
+
+
+ 91 +
+
+ +
+
+
/**
+
+
+
+ 92 +
+
+ +
+
+
 * A rule with a name, application function, and rule sets.
+
+
+
+ 93 +
+
+ +
+
+
 *
+
+
+
+ 94 +
+
+ +
+
+
 * # Fields
+
+
+
+ 95 +
+
+ +
+
+
 * - `name` The name of the rule.
+
+
+
+ 96 +
+
+ +
+
+
 * - `application` The function to apply the rule.
+
+
+
+ 97 +
+
+ +
+
+
 * - `rule_sets` A list of rule set names and priorities that this rule is a part of. This is used to populate rulesets at runtime.
+
+
+
+ 98 +
+
+ +
+
+
 */
+
+
+
+ 99 +
+
+ +
+
+
#[derive(Clone, Debug)]
+
+
+
+ 100 +
+
+ +
+
+
pub struct Rule<'a> {
+
+
+
+ 101 +
+
+ +
+
+
    pub name: &'a str,
+
+
+
+ 102 +
+
+ +
+
+
    pub application: fn(&Expression, &Model) -> ApplicationResult,
+
+
+
+ 103 +
+
+ +
+
+
    pub rule_sets: &'a [(&'a str, u8)], // (name, priority). At runtime, we add the rule to rulesets
+
+
+
+ 104 +
+
+ +
+
+
}
+
+
+
+ 105 +
+
+ +
+
+

+            
+
+
+ 106 +
+
+ +
+
+
impl<'a> Rule<'a> {
+
+
+
+ 107 +
+
+ +
+
+
    pub const fn new(
+
+
+
+ 108 +
+
+ +
+
+
        name: &'a str,
+
+
+
+ 109 +
+
+ +
+
+
        application: fn(&Expression, &Model) -> ApplicationResult,
+
+
+
+ 110 +
+
+ +
+
+
        rule_sets: &'a [(&'static str, u8)],
+
+
+
+ 111 +
+
+ +
+
+
    ) -> Self {
+
+
+
+ 112 +
+
+ +
+
+
        Self {
+
+
+
+ 113 +
+
+ +
+
+
            name,
+
+
+
+ 114 +
+
+ +
+
+
            application,
+
+
+
+ 115 +
+
+ +
+
+
            rule_sets,
+
+
+
+ 116 +
+
+ +
+
+
        }
+
+
+
+ 117 +
+
+ +
+
+
    }
+
+
+
+ 118 +
+
+ +
+
+

+            
+
+
+ 119 +
+
+ 770670 +
+
+
    pub fn apply(&self, expr: &Expression, mdl: &Model) -> ApplicationResult {
+
+
+
+ 120 +
+
+ 770670 +
+
+
        (self.application)(expr, mdl)
+
+
+
+ 121 +
+
+ 770670 +
+
+
    }
+
+
+
+ 122 +
+
+ +
+
+
}
+
+
+
+ 123 +
+
+ +
+
+

+            
+
+
+ 124 +
+
+ +
+
+
impl<'a> Display for Rule<'a> {
+
+
+
+ 125 +
+
+ +
+
+
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+
+
+
+ 126 +
+
+ +
+
+
        write!(f, "{}", self.name)
+
+
+
+ 127 +
+
+ +
+
+
    }
+
+
+
+ 128 +
+
+ +
+
+
}
+
+
+
+ 129 +
+
+ +
+
+

+            
+
+
+ 130 +
+
+ +
+
+
impl<'a> PartialEq for Rule<'a> {
+
+
+
+ 131 +
+
+ 39330 +
+
+
    fn eq(&self, other: &Self) -> bool {
+
+
+
+ 132 +
+
+ 39330 +
+
+
        self.name == other.name
+
+
+
+ 133 +
+
+ 39330 +
+
+
    }
+
+
+
+ 134 +
+
+ +
+
+
}
+
+
+
+ 135 +
+
+ +
+
+

+            
+
+
+ 136 +
+
+ +
+
+
impl<'a> Eq for Rule<'a> {}
+
+
+
+ 137 +
+
+ +
+
+

+            
+
+
+ 138 +
+
+ +
+
+
impl<'a> Hash for Rule<'a> {
+
+
+
+ 139 +
+
+ 62280 +
+
+
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+
+
+
+ 140 +
+
+ 62280 +
+
+
        self.name.hash(state);
+
+
+
+ 141 +
+
+ 62280 +
+
+
    }
+
+
+
+ 142 +
+
+ +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/rule_set.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/rule_set.rs.html new file mode 100644 index 0000000000..7fc3f858af --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rule_engine/rule_set.rs.html @@ -0,0 +1,2809 @@ + + + + + Grcov report - rule_set.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use std::collections::{HashMap, HashSet};
+
+
+
+ 2 +
+
+ +
+
+
use std::fmt::{Display, Formatter};
+
+
+
+ 3 +
+
+ +
+
+
use std::hash::Hash;
+
+
+
+ 4 +
+
+ +
+
+
use std::sync::OnceLock;
+
+
+
+ 5 +
+
+ +
+
+

+            
+
+
+ 6 +
+
+ +
+
+
use log::warn;
+
+
+
+ 7 +
+
+ +
+
+

+            
+
+
+ 8 +
+
+ +
+
+
use crate::rule_engine::{get_rule_set_by_name, get_rules, Rule};
+
+
+
+ 9 +
+
+ +
+
+
use crate::solver::SolverFamily;
+
+
+
+ 10 +
+
+ +
+
+

+            
+
+
+ 11 +
+
+ +
+
+
/// A set of rules with a name, priority, and dependencies.
+
+
+
+ 12 +
+
+ +
+
+
#[derive(Clone, Debug)]
+
+
+
+ 13 +
+
+ +
+
+
pub struct RuleSet<'a> {
+
+
+
+ 14 +
+
+ +
+
+
    /// The name of the rule set.
+
+
+
+ 15 +
+
+ +
+
+
    pub name: &'a str,
+
+
+
+ 16 +
+
+ +
+
+
    /// Order of the RuleSet. Used to establish a consistent order of operations when resolving rules.
+
+
+
+ 17 +
+
+ +
+
+
    /// If two RuleSets overlap (contain the same rule but with different priorities), the RuleSet with the higher order will be used as the source of truth.
+
+
+
+ 18 +
+
+ +
+
+
    pub order: u8,
+
+
+
+ 19 +
+
+ +
+
+
    /// A map of rules to their priorities. This will be lazily initialized at runtime.
+
+
+
+ 20 +
+
+ +
+
+
    rules: OnceLock<HashMap<&'a Rule<'a>, u8>>,
+
+
+
+ 21 +
+
+ +
+
+
    /// The names of the rule sets that this rule set depends on.
+
+
+
+ 22 +
+
+ +
+
+
    dependency_rs_names: &'a [&'a str],
+
+
+
+ 23 +
+
+ +
+
+
    dependencies: OnceLock<HashSet<&'a RuleSet<'a>>>,
+
+
+
+ 24 +
+
+ +
+
+
    /// The solver families that this rule set applies to.
+
+
+
+ 25 +
+
+ +
+
+
    pub solver_families: &'a [SolverFamily],
+
+
+
+ 26 +
+
+ +
+
+
}
+
+
+
+ 27 +
+
+ +
+
+

+            
+
+
+ 28 +
+
+ +
+
+
impl<'a> RuleSet<'a> {
+
+
+
+ 29 +
+
+ +
+
+
    pub const fn new(
+
+
+
+ 30 +
+
+ +
+
+
        name: &'a str,
+
+
+
+ 31 +
+
+ +
+
+
        order: u8,
+
+
+
+ 32 +
+
+ +
+
+
        dependencies: &'a [&'a str],
+
+
+
+ 33 +
+
+ +
+
+
        solver_families: &'a [SolverFamily],
+
+
+
+ 34 +
+
+ +
+
+
    ) -> Self {
+
+
+
+ 35 +
+
+ +
+
+
        Self {
+
+
+
+ 36 +
+
+ +
+
+
            name,
+
+
+
+ 37 +
+
+ +
+
+
            order,
+
+
+
+ 38 +
+
+ +
+
+
            dependency_rs_names: dependencies,
+
+
+
+ 39 +
+
+ +
+
+
            solver_families,
+
+
+
+ 40 +
+
+ +
+
+
            rules: OnceLock::new(),
+
+
+
+ 41 +
+
+ +
+
+
            dependencies: OnceLock::new(),
+
+
+
+ 42 +
+
+ +
+
+
        }
+
+
+
+ 43 +
+
+ +
+
+
    }
+
+
+
+ 44 +
+
+ +
+
+

+            
+
+
+ 45 +
+
+ +
+
+
    /// Get the rules of this rule set, evaluating them lazily if necessary
+
+
+
+ 46 +
+
+ +
+
+
    /// Returns a `&HashMap<&Rule, u8>` where the key is the rule and the value is the priority of the rule.
+
+
+
+ 47 +
+
+ 495 +
+
+
    pub fn get_rules(&self) -> &HashMap<&'a Rule<'a>, u8> {
+
+
+
+ 48 +
+
+ 495 +
+
+
        match self.rules.get() {
+
+
+
+ 49 +
+
+ +
+
+
            None => {
+
+
+
+ 50 +
+
+ 165 +
+
+
                let rules = self.resolve_rules();
+
+
+
+ 51 +
+
+ 165 +
+
+
                let _ = self.rules.set(rules); // Try to set the rules, but ignore if it fails.
+
+
+
+ 52 +
+
+ 165 +
+
+

+            
+
+
+ 53 +
+
+ 165 +
+
+
                // At this point, the rules cell is guaranteed to be set, so we can unwrap safely.
+
+
+
+ 54 +
+
+ 165 +
+
+
                // see: https://doc.rust-lang.org/stable/std/sync/struct.OnceLock.html#method.set
+
+
+
+ 55 +
+
+ 165 +
+
+
                #[allow(clippy::unwrap_used)]
+
+
+
+ 56 +
+
+ 165 +
+
+
                self.rules.get().unwrap()
+
+
+
+ 57 +
+
+ +
+
+
            }
+
+
+
+ 58 +
+
+ 330 +
+
+
            Some(rules) => rules,
+
+
+
+ 59 +
+
+ +
+
+
        }
+
+
+
+ 60 +
+
+ 495 +
+
+
    }
+
+
+
+ 61 +
+
+ +
+
+

+            
+
+
+ 62 +
+
+ +
+
+
    /// Get the dependencies of this rule set, evaluating them lazily if necessary
+
+
+
+ 63 +
+
+ +
+
+
    /// Returns a `&HashSet<&RuleSet>` of the rule sets that this rule set depends on.
+
+
+
+ 64 +
+
+ +
+
+
    #[allow(clippy::mutable_key_type)] // RuleSet is 'static so it's fine
+
+
+
+ 65 +
+
+ 360 +
+
+
    pub fn get_dependencies(&self) -> &HashSet<&'static RuleSet> {
+
+
+
+ 66 +
+
+ 360 +
+
+
        match self.dependencies.get() {
+
+
+
+ 67 +
+
+ +
+
+
            None => {
+
+
+
+ 68 +
+
+ 120 +
+
+
                let dependencies = self.resolve_dependencies();
+
+
+
+ 69 +
+
+ 120 +
+
+
                let _ = self.dependencies.set(dependencies); // Try to set the dependencies, but ignore if it fails.
+
+
+
+ 70 +
+
+ 120 +
+
+

+            
+
+
+ 71 +
+
+ 120 +
+
+
                // At this point, the dependencies cell is guaranteed to be set, so we can unwrap safely.
+
+
+
+ 72 +
+
+ 120 +
+
+
                // see: https://doc.rust-lang.org/stable/std/sync/struct.OnceLock.html#method.set
+
+
+
+ 73 +
+
+ 120 +
+
+
                #[allow(clippy::unwrap_used)]
+
+
+
+ 74 +
+
+ 120 +
+
+
                self.dependencies.get().unwrap()
+
+
+
+ 75 +
+
+ +
+
+
            }
+
+
+
+ 76 +
+
+ 240 +
+
+
            Some(dependencies) => dependencies,
+
+
+
+ 77 +
+
+ +
+
+
        }
+
+
+
+ 78 +
+
+ 360 +
+
+
    }
+
+
+
+ 79 +
+
+ +
+
+

+            
+
+
+ 80 +
+
+ +
+
+
    /// Get the dependencies of this rule set, including itself
+
+
+
+ 81 +
+
+ +
+
+
    #[allow(clippy::mutable_key_type)] // RuleSet is 'static so it's fine
+
+
+
+ 82 +
+
+ 180 +
+
+
    pub fn with_dependencies(&self) -> HashSet<&'static RuleSet> {
+
+
+
+ 83 +
+
+ 180 +
+
+
        let mut deps = self.get_dependencies().clone();
+
+
+
+ 84 +
+
+ 180 +
+
+
        deps.insert(self);
+
+
+
+ 85 +
+
+ 180 +
+
+
        deps
+
+
+
+ 86 +
+
+ 180 +
+
+
    }
+
+
+
+ 87 +
+
+ +
+
+

+            
+
+
+ 88 +
+
+ +
+
+
    /// Resolve the rules of this rule set ("reverse the arrows")
+
+
+
+ 89 +
+
+ 165 +
+
+
    fn resolve_rules(&self) -> HashMap<&'a Rule<'a>, u8> {
+
+
+
+ 90 +
+
+ 165 +
+
+
        let mut rules = HashMap::new();
+
+
+
+ 91 +
+
+ +
+
+

+            
+
+
+ 92 +
+
+ 4785 +
+
+
        for rule in get_rules() {
+
+
+
+ 93 +
+
+ 4620 +
+
+
            let mut found = false;
+
+
+
+ 94 +
+
+ 4620 +
+
+
            let mut priority: u8 = 0;
+
+
+
+ 95 +
+
+ +
+
+

+            
+
+
+ 96 +
+
+ 7695 +
+
+
            for (name, p) in rule.rule_sets {
+
+
+
+ 97 +
+
+ 4620 +
+
+
                if *name == self.name {
+
+
+
+ 98 +
+
+ 1545 +
+
+
                    found = true;
+
+
+
+ 99 +
+
+ 1545 +
+
+
                    priority = *p;
+
+
+
+ 100 +
+
+ 1545 +
+
+
                    break;
+
+
+
+ 101 +
+
+ 3075 +
+
+
                }
+
+
+
+ 102 +
+
+ +
+
+
            }
+
+
+
+ 103 +
+
+ +
+
+

+            
+
+
+ 104 +
+
+ 4620 +
+
+
            if found {
+
+
+
+ 105 +
+
+ 1545 +
+
+
                rules.insert(rule, priority);
+
+
+
+ 106 +
+
+ 3075 +
+
+
            }
+
+
+
+ 107 +
+
+ +
+
+
        }
+
+
+
+ 108 +
+
+ +
+
+

+            
+
+
+ 109 +
+
+ 165 +
+
+
        rules
+
+
+
+ 110 +
+
+ 165 +
+
+
    }
+
+
+
+ 111 +
+
+ +
+
+

+            
+
+
+ 112 +
+
+ +
+
+
    /// Recursively resolve the dependencies of this rule set.
+
+
+
+ 113 +
+
+ +
+
+
    #[allow(clippy::mutable_key_type)] // RuleSet is 'static so it's fine
+
+
+
+ 114 +
+
+ 180 +
+
+
    fn resolve_dependencies(&self) -> HashSet<&'static RuleSet> {
+
+
+
+ 115 +
+
+ 180 +
+
+
        let mut dependencies = HashSet::new();
+
+
+
+ 116 +
+
+ +
+
+

+            
+
+
+ 117 +
+
+ 240 +
+
+
        for dep in self.dependency_rs_names {
+
+
+
+ 118 +
+
+ 60 +
+
+
            match get_rule_set_by_name(dep) {
+
+
+
+ 119 +
+
+ +
+
+
                None => {
+
+
+
+ 120 +
+
+ +
+
+
                    warn!(
+
+
+
+ 121 +
+
+ +
+
+
                        "Rule set {} depends on non-existent rule set {}",
+
+
+
+ 122 +
+
+ +
+
+
                        &self.name, dep
+
+
+
+ 123 +
+
+ +
+
+
                    );
+
+
+
+ 124 +
+
+ +
+
+
                }
+
+
+
+ 125 +
+
+ 60 +
+
+
                Some(rule_set) => {
+
+
+
+ 126 +
+
+ 60 +
+
+
                    if !dependencies.contains(rule_set) {
+
+
+
+ 127 +
+
+ 60 +
+
+
                        // Prevent cycles
+
+
+
+ 128 +
+
+ 60 +
+
+
                        dependencies.insert(rule_set);
+
+
+
+ 129 +
+
+ 60 +
+
+
                        dependencies.extend(rule_set.resolve_dependencies());
+
+
+
+ 130 +
+
+ 60 +
+
+
                    }
+
+
+
+ 131 +
+
+ +
+
+
                }
+
+
+
+ 132 +
+
+ +
+
+
            }
+
+
+
+ 133 +
+
+ +
+
+
        }
+
+
+
+ 134 +
+
+ +
+
+

+            
+
+
+ 135 +
+
+ 180 +
+
+
        dependencies
+
+
+
+ 136 +
+
+ 180 +
+
+
    }
+
+
+
+ 137 +
+
+ +
+
+
}
+
+
+
+ 138 +
+
+ +
+
+

+            
+
+
+ 139 +
+
+ +
+
+
impl<'a> PartialEq for RuleSet<'a> {
+
+
+
+ 140 +
+
+ +
+
+
    fn eq(&self, other: &Self) -> bool {
+
+
+
+ 141 +
+
+ +
+
+
        self.name == other.name
+
+
+
+ 142 +
+
+ +
+
+
    }
+
+
+
+ 143 +
+
+ +
+
+
}
+
+
+
+ 144 +
+
+ +
+
+

+            
+
+
+ 145 +
+
+ +
+
+
impl<'a> Eq for RuleSet<'a> {}
+
+
+
+ 146 +
+
+ +
+
+

+            
+
+
+ 147 +
+
+ +
+
+
impl<'a> Hash for RuleSet<'a> {
+
+
+
+ 148 +
+
+ 960 +
+
+
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+
+
+
+ 149 +
+
+ 960 +
+
+
        self.name.hash(state);
+
+
+
+ 150 +
+
+ 960 +
+
+
    }
+
+
+
+ 151 +
+
+ +
+
+
}
+
+
+
+ 152 +
+
+ +
+
+

+            
+
+
+ 153 +
+
+ +
+
+
impl<'a> Display for RuleSet<'a> {
+
+
+
+ 154 +
+
+ +
+
+
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+
+
+
+ 155 +
+
+ +
+
+
        let n_rules = self.get_rules().len();
+
+
+
+ 156 +
+
+ +
+
+
        let solver_families = self
+
+
+
+ 157 +
+
+ +
+
+
            .solver_families
+
+
+
+ 158 +
+
+ +
+
+
            .iter()
+
+
+
+ 159 +
+
+ +
+
+
            .map(|f| f.to_string())
+
+
+
+ 160 +
+
+ +
+
+
            .collect::<Vec<String>>();
+
+
+
+ 161 +
+
+ +
+
+

+            
+
+
+ 162 +
+
+ +
+
+
        write!(
+
+
+
+ 163 +
+
+ +
+
+
            f,
+
+
+
+ 164 +
+
+ +
+
+
            "RuleSet {{\n\
+
+
+
+ 165 +
+
+ +
+
+
            \tname: {}\n\
+
+
+
+ 166 +
+
+ +
+
+
            \torder: {}\n\
+
+
+
+ 167 +
+
+ +
+
+
            \trules: {}\n\
+
+
+
+ 168 +
+
+ +
+
+
            \tsolver_families: {:?}\n\
+
+
+
+ 169 +
+
+ +
+
+
        }}",
+
+
+
+ 170 +
+
+ +
+
+
            self.name, self.order, n_rules, solver_families
+
+
+
+ 171 +
+
+ +
+
+
        )
+
+
+
+ 172 +
+
+ +
+
+
    }
+
+
+
+ 173 +
+
+ +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rules/base.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rules/base.rs.html new file mode 100644 index 0000000000..380c72d521 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rules/base.rs.html @@ -0,0 +1,8425 @@ + + + + + Grcov report - base.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use conjure_core::ast::{
+
+
+
+ 2 +
+
+ +
+
+
    Constant as Const, DecisionVariable, Domain, Expression as Expr, Range, SymbolTable,
+
+
+
+ 3 +
+
+ +
+
+
};
+
+
+
+ 4 +
+
+ +
+
+
use conjure_core::metadata::Metadata;
+
+
+
+ 5 +
+
+ +
+
+
use conjure_core::rule_engine::{
+
+
+
+ 6 +
+
+ +
+
+
    register_rule, register_rule_set, ApplicationError, ApplicationResult, Reduction,
+
+
+
+ 7 +
+
+ +
+
+
};
+
+
+
+ 8 +
+
+ +
+
+
use conjure_core::Model;
+
+
+
+ 9 +
+
+ +
+
+
use uniplate::uniplate::Uniplate;
+
+
+
+ 10 +
+
+ +
+
+

+            
+
+
+ 11 +
+
+ +
+
+
/*****************************************************************************/
+
+
+
+ 12 +
+
+ +
+
+
/*        This file contains basic rules for simplifying expressions         */
+
+
+
+ 13 +
+
+ +
+
+
/*****************************************************************************/
+
+
+
+ 14 +
+
+ +
+
+

+            
+
+
+ 15 +
+
+ +
+
+
register_rule_set!("Base", 150, ());
+
+
+
+ 16 +
+
+ +
+
+

+            
+
+
+ 17 +
+
+ +
+
+
/**
+
+
+
+ 18 +
+
+ +
+
+
 * Remove nothing's from expressions:
+
+
+
+ 19 +
+
+ +
+
+
 * ```text
+
+
+
+ 20 +
+
+ +
+
+
 * and([a, nothing, b]) = and([a, b])
+
+
+
+ 21 +
+
+ +
+
+
 * sum([a, nothing, b]) = sum([a, b])
+
+
+
+ 22 +
+
+ +
+
+
 * sum_leq([a, nothing, b], c) = sum_leq([a, b], c)
+
+
+
+ 23 +
+
+ 1 +
+
+
 * ...
+
+
+
+ 24 +
+
+ 1 +
+
+
 * ```
+
+
+
+ 25 +
+
+ 1 +
+
+
*/
+
+
+
+ 26 +
+
+ +
+
+
#[register_rule(("Base", 100))]
+
+
+
+ 27 +
+
+ 29610 +
+
+
fn remove_nothings(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 28 +
+
+ 29610 +
+
+
    fn remove_nothings(exprs: Vec<Expr>) -> Result<Vec<Expr>, ApplicationError> {
+
+
+
+ 29 +
+
+ 29610 +
+
+
        let mut changed = false;
+
+
+
+ 30 +
+
+ 29610 +
+
+
        let mut new_exprs = Vec::new();
+
+
+
+ 31 +
+
+ +
+
+

+            
+
+
+ 32 +
+
+ 62775 +
+
+
        for e in exprs {
+
+
+
+ 33 +
+
+ 33165 +
+
+
            match e.clone() {
+
+
+
+ 34 +
+
+ +
+
+
                Expr::Nothing => {
+
+
+
+ 35 +
+
+ +
+
+
                    changed = true;
+
+
+
+ 36 +
+
+ +
+
+
                }
+
+
+
+ 37 +
+
+ 33165 +
+
+
                _ => new_exprs.push(e),
+
+
+
+ 38 +
+
+ +
+
+
            }
+
+
+
+ 39 +
+
+ +
+
+
        }
+
+
+
+ 40 +
+
+ +
+
+

+            
+
+
+ 41 +
+
+ 29610 +
+
+
        if changed {
+
+
+
+ 42 +
+
+ +
+
+
            Ok(new_exprs)
+
+
+
+ 43 +
+
+ +
+
+
        } else {
+
+
+
+ 44 +
+
+ 29610 +
+
+
            Err(ApplicationError::RuleNotApplicable)
+
+
+
+ 45 +
+
+ +
+
+
        }
+
+
+
+ 46 +
+
+ 29610 +
+
+
    }
+
+
+
+ 47 +
+
+ +
+
+

+            
+
+
+ 48 +
+
+ +
+
+
    fn get_lhs_rhs(sub: Vec<Expr>) -> (Vec<Expr>, Box<Expr>) {
+
+
+
+ 49 +
+
+ +
+
+
        if sub.is_empty() {
+
+
+
+ 50 +
+
+ +
+
+
            return (Vec::new(), Box::new(Expr::Nothing));
+
+
+
+ 51 +
+
+ +
+
+
        }
+
+
+
+ 52 +
+
+ +
+
+

+            
+
+
+ 53 +
+
+ +
+
+
        let lhs = sub[..(sub.len() - 1)].to_vec();
+
+
+
+ 54 +
+
+ +
+
+
        let rhs = Box::new(sub[sub.len() - 1].clone());
+
+
+
+ 55 +
+
+ +
+
+
        (lhs, rhs)
+
+
+
+ 56 +
+
+ +
+
+
    }
+
+
+
+ 57 +
+
+ +
+
+

+            
+
+
+ 58 +
+
+ 29610 +
+
+
    let new_sub = remove_nothings(expr.children())?;
+
+
+
+ 59 +
+
+ +
+
+

+            
+
+
+ 60 +
+
+ +
+
+
    match expr {
+
+
+
+ 61 +
+
+ +
+
+
        Expr::And(md, _) => Ok(Reduction::pure(Expr::And(md.clone(), new_sub))),
+
+
+
+ 62 +
+
+ +
+
+
        Expr::Or(md, _) => Ok(Reduction::pure(Expr::Or(md.clone(), new_sub))),
+
+
+
+ 63 +
+
+ +
+
+
        Expr::Sum(md, _) => Ok(Reduction::pure(Expr::Sum(md.clone(), new_sub))),
+
+
+
+ 64 +
+
+ +
+
+
        Expr::SumEq(md, _, _) => {
+
+
+
+ 65 +
+
+ +
+
+
            let (lhs, rhs) = get_lhs_rhs(new_sub);
+
+
+
+ 66 +
+
+ +
+
+
            Ok(Reduction::pure(Expr::SumEq(md.clone(), lhs, rhs)))
+
+
+
+ 67 +
+
+ +
+
+
        }
+
+
+
+ 68 +
+
+ +
+
+
        Expr::SumLeq(md, _lhs, _rhs) => {
+
+
+
+ 69 +
+
+ +
+
+
            let (lhs, rhs) = get_lhs_rhs(new_sub);
+
+
+
+ 70 +
+
+ +
+
+
            Ok(Reduction::pure(Expr::SumLeq(md.clone(), lhs, rhs)))
+
+
+
+ 71 +
+
+ +
+
+
        }
+
+
+
+ 72 +
+
+ +
+
+
        Expr::SumGeq(md, _lhs, _rhs) => {
+
+
+
+ 73 +
+
+ +
+
+
            let (lhs, rhs) = get_lhs_rhs(new_sub);
+
+
+
+ 74 +
+
+ +
+
+
            Ok(Reduction::pure(Expr::SumGeq(md.clone(), lhs, rhs)))
+
+
+
+ 75 +
+
+ +
+
+
        }
+
+
+
+ 76 +
+
+ +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 77 +
+
+ +
+
+
    }
+
+
+
+ 78 +
+
+ 29610 +
+
+
}
+
+
+
+ 79 +
+
+ +
+
+

+            
+
+
+ 80 +
+
+ +
+
+
/**
+
+
+
+ 81 +
+
+ +
+
+
 * Remove empty expressions:
+
+
+
+ 82 +
+
+ +
+
+
 * ```text
+
+
+
+ 83 +
+
+ 1 +
+
+
 * [] = Nothing
+
+
+
+ 84 +
+
+ 1 +
+
+
 * ```
+
+
+
+ 85 +
+
+ 1 +
+
+
 */
+
+
+
+ 86 +
+
+ +
+
+
#[register_rule(("Base", 100))]
+
+
+
+ 87 +
+
+ 29610 +
+
+
fn empty_to_nothing(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 88 +
+
+ 29610 +
+
+
    match expr {
+
+
+
+ 89 +
+
+ +
+
+
        Expr::Nothing | Expr::Reference(_, _) | Expr::Constant(_, _) => {
+
+
+
+ 90 +
+
+ 18630 +
+
+
            Err(ApplicationError::RuleNotApplicable)
+
+
+
+ 91 +
+
+ +
+
+
        }
+
+
+
+ 92 +
+
+ +
+
+
        _ => {
+
+
+
+ 93 +
+
+ 10980 +
+
+
            if expr.children().is_empty() {
+
+
+
+ 94 +
+
+ +
+
+
                Ok(Reduction::pure(Expr::Nothing))
+
+
+
+ 95 +
+
+ +
+
+
            } else {
+
+
+
+ 96 +
+
+ 10980 +
+
+
                Err(ApplicationError::RuleNotApplicable)
+
+
+
+ 97 +
+
+ +
+
+
            }
+
+
+
+ 98 +
+
+ +
+
+
        }
+
+
+
+ 99 +
+
+ +
+
+
    }
+
+
+
+ 100 +
+
+ 29610 +
+
+
}
+
+
+
+ 101 +
+
+ +
+
+

+            
+
+
+ 102 +
+
+ +
+
+
/**
+
+
+
+ 103 +
+
+ +
+
+
 * Evaluate sum of constants:
+
+
+
+ 104 +
+
+ +
+
+
 * ```text
+
+
+
+ 105 +
+
+ 1 +
+
+
 * sum([1, 2, 3]) = 6
+
+
+
+ 106 +
+
+ 1 +
+
+
 * ```
+
+
+
+ 107 +
+
+ 1 +
+
+
 */
+
+
+
+ 108 +
+
+ +
+
+
#[register_rule(("Base", 100))]
+
+
+
+ 109 +
+
+ 29655 +
+
+
fn sum_constants(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 110 +
+
+ 29655 +
+
+
    match expr {
+
+
+
+ 111 +
+
+ 60 +
+
+
        Expr::Sum(_, exprs) => {
+
+
+
+ 112 +
+
+ 60 +
+
+
            let mut sum = 0;
+
+
+
+ 113 +
+
+ 60 +
+
+
            let mut new_exprs = Vec::new();
+
+
+
+ 114 +
+
+ 60 +
+
+
            let mut changed = false;
+
+
+
+ 115 +
+
+ 225 +
+
+
            for e in exprs {
+
+
+
+ 116 +
+
+ 120 +
+
+
                match e {
+
+
+
+ 117 +
+
+ 120 +
+
+
                    Expr::Constant(_metadata, Const::Int(i)) => {
+
+
+
+ 118 +
+
+ 120 +
+
+
                        sum += i;
+
+
+
+ 119 +
+
+ 120 +
+
+
                        changed = true;
+
+
+
+ 120 +
+
+ 120 +
+
+
                    }
+
+
+
+ 121 +
+
+ 45 +
+
+
                    _ => new_exprs.push(e.clone()),
+
+
+
+ 122 +
+
+ +
+
+
                }
+
+
+
+ 123 +
+
+ +
+
+
            }
+
+
+
+ 124 +
+
+ 60 +
+
+
            if !changed {
+
+
+
+ 125 +
+
+ 15 +
+
+
                return Err(ApplicationError::RuleNotApplicable);
+
+
+
+ 126 +
+
+ 45 +
+
+
            }
+
+
+
+ 127 +
+
+ 45 +
+
+
            // TODO (kf77): Get existing metadata instead of creating a new one
+
+
+
+ 128 +
+
+ 45 +
+
+
            new_exprs.push(Expr::Constant(Metadata::new(), Const::Int(sum)));
+
+
+
+ 129 +
+
+ 45 +
+
+
            Ok(Reduction::pure(Expr::Sum(Metadata::new(), new_exprs))) // Let other rules handle only one Expr being contained in the sum
+
+
+
+ 130 +
+
+ +
+
+
        }
+
+
+
+ 131 +
+
+ 29595 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 132 +
+
+ +
+
+
    }
+
+
+
+ 133 +
+
+ 29655 +
+
+
}
+
+
+
+ 134 +
+
+ +
+
+

+            
+
+
+ 135 +
+
+ +
+
+
/**
+
+
+
+ 136 +
+
+ +
+
+
 * Unwrap trivial sums:
+
+
+
+ 137 +
+
+ +
+
+
 * ```text
+
+
+
+ 138 +
+
+ 1 +
+
+
 * sum([a]) = a
+
+
+
+ 139 +
+
+ 1 +
+
+
 * ```
+
+
+
+ 140 +
+
+ 1 +
+
+
 */
+
+
+
+ 141 +
+
+ +
+
+
#[register_rule(("Base", 100))]
+
+
+
+ 142 +
+
+ 29640 +
+
+
fn unwrap_sum(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 143 +
+
+ 45 +
+
+
    match expr {
+
+
+
+ 144 +
+
+ 45 +
+
+
        Expr::Sum(_, exprs) if (exprs.len() == 1) => Ok(Reduction::pure(exprs[0].clone())),
+
+
+
+ 145 +
+
+ 29610 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 146 +
+
+ +
+
+
    }
+
+
+
+ 147 +
+
+ 29640 +
+
+
}
+
+
+
+ 148 +
+
+ +
+
+

+            
+
+
+ 149 +
+
+ +
+
+
/**
+
+
+
+ 150 +
+
+ +
+
+
 * Flatten nested sums:
+
+
+
+ 151 +
+
+ +
+
+
 * ```text
+
+
+
+ 152 +
+
+ 1 +
+
+
 * sum(sum(a, b), c) = sum(a, b, c)
+
+
+
+ 153 +
+
+ 1 +
+
+
 * ```
+
+
+
+ 154 +
+
+ 1 +
+
+
 */
+
+
+
+ 155 +
+
+ +
+
+
#[register_rule(("Base", 100))]
+
+
+
+ 156 +
+
+ 29610 +
+
+
pub fn flatten_nested_sum(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 157 +
+
+ 29610 +
+
+
    match expr {
+
+
+
+ 158 +
+
+ 15 +
+
+
        Expr::Sum(metadata, exprs) => {
+
+
+
+ 159 +
+
+ 15 +
+
+
            let mut new_exprs = Vec::new();
+
+
+
+ 160 +
+
+ 15 +
+
+
            let mut changed = false;
+
+
+
+ 161 +
+
+ 45 +
+
+
            for e in exprs {
+
+
+
+ 162 +
+
+ 30 +
+
+
                match e {
+
+
+
+ 163 +
+
+ 15 +
+
+
                    Expr::Sum(_, sub_exprs) => {
+
+
+
+ 164 +
+
+ 15 +
+
+
                        changed = true;
+
+
+
+ 165 +
+
+ 45 +
+
+
                        for e in sub_exprs {
+
+
+
+ 166 +
+
+ 30 +
+
+
                            new_exprs.push(e.clone());
+
+
+
+ 167 +
+
+ 30 +
+
+
                        }
+
+
+
+ 168 +
+
+ +
+
+
                    }
+
+
+
+ 169 +
+
+ 15 +
+
+
                    _ => new_exprs.push(e.clone()),
+
+
+
+ 170 +
+
+ +
+
+
                }
+
+
+
+ 171 +
+
+ +
+
+
            }
+
+
+
+ 172 +
+
+ 15 +
+
+
            if !changed {
+
+
+
+ 173 +
+
+ +
+
+
                return Err(ApplicationError::RuleNotApplicable);
+
+
+
+ 174 +
+
+ 15 +
+
+
            }
+
+
+
+ 175 +
+
+ 15 +
+
+
            Ok(Reduction::pure(Expr::Sum(metadata.clone(), new_exprs)))
+
+
+
+ 176 +
+
+ +
+
+
        }
+
+
+
+ 177 +
+
+ 29595 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 178 +
+
+ +
+
+
    }
+
+
+
+ 179 +
+
+ 29610 +
+
+
}
+
+
+
+ 180 +
+
+ +
+
+

+            
+
+
+ 181 +
+
+ +
+
+
/**
+
+
+
+ 182 +
+
+ +
+
+
* Unwrap nested `or`
+
+
+
+ 183 +
+
+ +
+
+

+            
+
+
+ 184 +
+
+ +
+
+
* ```text
+
+
+
+ 185 +
+
+ 1 +
+
+
* or(or(a, b), c) = or(a, b, c)
+
+
+
+ 186 +
+
+ 1 +
+
+
* ```
+
+
+
+ 187 +
+
+ 1 +
+
+
 */
+
+
+
+ 188 +
+
+ +
+
+
#[register_rule(("Base", 100))]
+
+
+
+ 189 +
+
+ 29640 +
+
+
fn unwrap_nested_or(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 190 +
+
+ 29640 +
+
+
    match expr {
+
+
+
+ 191 +
+
+ 2205 +
+
+
        Expr::Or(metadata, exprs) => {
+
+
+
+ 192 +
+
+ 2205 +
+
+
            let mut new_exprs = Vec::new();
+
+
+
+ 193 +
+
+ 2205 +
+
+
            let mut changed = false;
+
+
+
+ 194 +
+
+ 6615 +
+
+
            for e in exprs {
+
+
+
+ 195 +
+
+ 4410 +
+
+
                match e {
+
+
+
+ 196 +
+
+ 15 +
+
+
                    Expr::Or(_, exprs) => {
+
+
+
+ 197 +
+
+ 15 +
+
+
                        changed = true;
+
+
+
+ 198 +
+
+ 45 +
+
+
                        for e in exprs {
+
+
+
+ 199 +
+
+ 30 +
+
+
                            new_exprs.push(e.clone());
+
+
+
+ 200 +
+
+ 30 +
+
+
                        }
+
+
+
+ 201 +
+
+ +
+
+
                    }
+
+
+
+ 202 +
+
+ 4395 +
+
+
                    _ => new_exprs.push(e.clone()),
+
+
+
+ 203 +
+
+ +
+
+
                }
+
+
+
+ 204 +
+
+ +
+
+
            }
+
+
+
+ 205 +
+
+ 2205 +
+
+
            if !changed {
+
+
+
+ 206 +
+
+ 2190 +
+
+
                return Err(ApplicationError::RuleNotApplicable);
+
+
+
+ 207 +
+
+ 15 +
+
+
            }
+
+
+
+ 208 +
+
+ 15 +
+
+
            Ok(Reduction::pure(Expr::Or(metadata.clone(), new_exprs)))
+
+
+
+ 209 +
+
+ +
+
+
        }
+
+
+
+ 210 +
+
+ 27435 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 211 +
+
+ +
+
+
    }
+
+
+
+ 212 +
+
+ 29640 +
+
+
}
+
+
+
+ 213 +
+
+ +
+
+

+            
+
+
+ 214 +
+
+ +
+
+
/**
+
+
+
+ 215 +
+
+ +
+
+
* Unwrap nested `and`
+
+
+
+ 216 +
+
+ +
+
+

+            
+
+
+ 217 +
+
+ +
+
+
* ```text
+
+
+
+ 218 +
+
+ 1 +
+
+
* and(and(a, b), c) = and(a, b, c)
+
+
+
+ 219 +
+
+ 1 +
+
+
* ```
+
+
+
+ 220 +
+
+ 1 +
+
+
 */
+
+
+
+ 221 +
+
+ +
+
+
#[register_rule(("Base", 100))]
+
+
+
+ 222 +
+
+ 29640 +
+
+
fn unwrap_nested_and(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 223 +
+
+ 29640 +
+
+
    match expr {
+
+
+
+ 224 +
+
+ 1560 +
+
+
        Expr::And(metadata, exprs) => {
+
+
+
+ 225 +
+
+ 1560 +
+
+
            let mut new_exprs = Vec::new();
+
+
+
+ 226 +
+
+ 1560 +
+
+
            let mut changed = false;
+
+
+
+ 227 +
+
+ 9480 +
+
+
            for e in exprs {
+
+
+
+ 228 +
+
+ 7920 +
+
+
                match e {
+
+
+
+ 229 +
+
+ 345 +
+
+
                    Expr::And(_, exprs) => {
+
+
+
+ 230 +
+
+ 345 +
+
+
                        changed = true;
+
+
+
+ 231 +
+
+ 1110 +
+
+
                        for e in exprs {
+
+
+
+ 232 +
+
+ 765 +
+
+
                            new_exprs.push(e.clone());
+
+
+
+ 233 +
+
+ 765 +
+
+
                        }
+
+
+
+ 234 +
+
+ +
+
+
                    }
+
+
+
+ 235 +
+
+ 7575 +
+
+
                    _ => new_exprs.push(e.clone()),
+
+
+
+ 236 +
+
+ +
+
+
                }
+
+
+
+ 237 +
+
+ +
+
+
            }
+
+
+
+ 238 +
+
+ 1560 +
+
+
            if !changed {
+
+
+
+ 239 +
+
+ 1215 +
+
+
                return Err(ApplicationError::RuleNotApplicable);
+
+
+
+ 240 +
+
+ 345 +
+
+
            }
+
+
+
+ 241 +
+
+ 345 +
+
+
            Ok(Reduction::pure(Expr::And(metadata.clone(), new_exprs)))
+
+
+
+ 242 +
+
+ +
+
+
        }
+
+
+
+ 243 +
+
+ 28080 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 244 +
+
+ +
+
+
    }
+
+
+
+ 245 +
+
+ 29640 +
+
+
}
+
+
+
+ 246 +
+
+ +
+
+

+            
+
+
+ 247 +
+
+ +
+
+
/**
+
+
+
+ 248 +
+
+ +
+
+
* Remove double negation:
+
+
+
+ 249 +
+
+ +
+
+

+            
+
+
+ 250 +
+
+ +
+
+
* ```text
+
+
+
+ 251 +
+
+ 1 +
+
+
* not(not(a)) = a
+
+
+
+ 252 +
+
+ 1 +
+
+
* ```
+
+
+
+ 253 +
+
+ 1 +
+
+
 */
+
+
+
+ 254 +
+
+ +
+
+
#[register_rule(("Base", 100))]
+
+
+
+ 255 +
+
+ 29625 +
+
+
fn remove_double_negation(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 256 +
+
+ 29625 +
+
+
    match expr {
+
+
+
+ 257 +
+
+ 15 +
+
+
        Expr::Not(_, contents) => match contents.as_ref() {
+
+
+
+ 258 +
+
+ 15 +
+
+
            Expr::Not(_, expr_box) => Ok(Reduction::pure(*expr_box.clone())),
+
+
+
+ 259 +
+
+ +
+
+
            _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 260 +
+
+ +
+
+
        },
+
+
+
+ 261 +
+
+ 29610 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 262 +
+
+ +
+
+
    }
+
+
+
+ 263 +
+
+ 29625 +
+
+
}
+
+
+
+ 264 +
+
+ +
+
+

+            
+
+
+ 265 +
+
+ +
+
+
/**
+
+
+
+ 266 +
+
+ +
+
+
 * Remove trivial `and` (only one element):
+
+
+
+ 267 +
+
+ +
+
+
 * ```text
+
+
+
+ 268 +
+
+ 1 +
+
+
 * and([a]) = a
+
+
+
+ 269 +
+
+ 1 +
+
+
 * ```
+
+
+
+ 270 +
+
+ 1 +
+
+
 */
+
+
+
+ 271 +
+
+ +
+
+
#[register_rule(("Base", 100))]
+
+
+
+ 272 +
+
+ 29625 +
+
+
fn remove_trivial_and(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 273 +
+
+ 29625 +
+
+
    match expr {
+
+
+
+ 274 +
+
+ 1545 +
+
+
        Expr::And(_, exprs) => {
+
+
+
+ 275 +
+
+ 1545 +
+
+
            if exprs.len() == 1 {
+
+
+
+ 276 +
+
+ 15 +
+
+
                return Ok(Reduction::pure(exprs[0].clone()));
+
+
+
+ 277 +
+
+ 1530 +
+
+
            }
+
+
+
+ 278 +
+
+ 1530 +
+
+
            Err(ApplicationError::RuleNotApplicable)
+
+
+
+ 279 +
+
+ +
+
+
        }
+
+
+
+ 280 +
+
+ 28080 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 281 +
+
+ +
+
+
    }
+
+
+
+ 282 +
+
+ 29625 +
+
+
}
+
+
+
+ 283 +
+
+ +
+
+

+            
+
+
+ 284 +
+
+ +
+
+
/**
+
+
+
+ 285 +
+
+ +
+
+
 * Remove trivial `or` (only one element):
+
+
+
+ 286 +
+
+ +
+
+
 * ```text
+
+
+
+ 287 +
+
+ 1 +
+
+
 * or([a]) = a
+
+
+
+ 288 +
+
+ 1 +
+
+
 * ```
+
+
+
+ 289 +
+
+ 1 +
+
+
 */
+
+
+
+ 290 +
+
+ +
+
+
#[register_rule(("Base", 100))]
+
+
+
+ 291 +
+
+ 29625 +
+
+
fn remove_trivial_or(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 292 +
+
+ 29625 +
+
+
    match expr {
+
+
+
+ 293 +
+
+ 2190 +
+
+
        Expr::Or(_, exprs) => {
+
+
+
+ 294 +
+
+ 2190 +
+
+
            if exprs.len() == 1 {
+
+
+
+ 295 +
+
+ 15 +
+
+
                return Ok(Reduction::pure(exprs[0].clone()));
+
+
+
+ 296 +
+
+ 2175 +
+
+
            }
+
+
+
+ 297 +
+
+ 2175 +
+
+
            Err(ApplicationError::RuleNotApplicable)
+
+
+
+ 298 +
+
+ +
+
+
        }
+
+
+
+ 299 +
+
+ 27435 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 300 +
+
+ +
+
+
    }
+
+
+
+ 301 +
+
+ 29625 +
+
+
}
+
+
+
+ 302 +
+
+ +
+
+

+            
+
+
+ 303 +
+
+ +
+
+
/**
+
+
+
+ 304 +
+
+ +
+
+
 * Remove constant bools from or expressions
+
+
+
+ 305 +
+
+ +
+
+
 * ```text
+
+
+
+ 306 +
+
+ +
+
+
 * or([true, a]) = true
+
+
+
+ 307 +
+
+ 1 +
+
+
 * or([false, a]) = a
+
+
+
+ 308 +
+
+ 1 +
+
+
 * ```
+
+
+
+ 309 +
+
+ 1 +
+
+
 */
+
+
+
+ 310 +
+
+ +
+
+
#[register_rule(("Base", 100))]
+
+
+
+ 311 +
+
+ 29640 +
+
+
fn remove_constants_from_or(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 312 +
+
+ 29640 +
+
+
    match expr {
+
+
+
+ 313 +
+
+ 2205 +
+
+
        Expr::Or(metadata, exprs) => {
+
+
+
+ 314 +
+
+ 2205 +
+
+
            let mut new_exprs = Vec::new();
+
+
+
+ 315 +
+
+ 2205 +
+
+
            let mut changed = false;
+
+
+
+ 316 +
+
+ 6585 +
+
+
            for e in exprs {
+
+
+
+ 317 +
+
+ 15 +
+
+
                match e {
+
+
+
+ 318 +
+
+ 15 +
+
+
                    Expr::Constant(metadata, Const::Bool(val)) => {
+
+
+
+ 319 +
+
+ 15 +
+
+
                        if *val {
+
+
+
+ 320 +
+
+ +
+
+
                            // If we find a true, the whole expression is true
+
+
+
+ 321 +
+
+ 15 +
+
+
                            return Ok(Reduction::pure(Expr::Constant(
+
+
+
+ 322 +
+
+ 15 +
+
+
                                metadata.clone(),
+
+
+
+ 323 +
+
+ 15 +
+
+
                                Const::Bool(true),
+
+
+
+ 324 +
+
+ 15 +
+
+
                            )));
+
+
+
+ 325 +
+
+ +
+
+
                        } else {
+
+
+
+ 326 +
+
+ +
+
+
                            // If we find a false, we can ignore it
+
+
+
+ 327 +
+
+ +
+
+
                            changed = true;
+
+
+
+ 328 +
+
+ +
+
+
                        }
+
+
+
+ 329 +
+
+ +
+
+
                    }
+
+
+
+ 330 +
+
+ 4380 +
+
+
                    _ => new_exprs.push(e.clone()),
+
+
+
+ 331 +
+
+ +
+
+
                }
+
+
+
+ 332 +
+
+ +
+
+
            }
+
+
+
+ 333 +
+
+ 2190 +
+
+
            if !changed {
+
+
+
+ 334 +
+
+ 2190 +
+
+
                return Err(ApplicationError::RuleNotApplicable);
+
+
+
+ 335 +
+
+ +
+
+
            }
+
+
+
+ 336 +
+
+ +
+
+
            Ok(Reduction::pure(Expr::Or(metadata.clone(), new_exprs)))
+
+
+
+ 337 +
+
+ +
+
+
        }
+
+
+
+ 338 +
+
+ 27435 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 339 +
+
+ +
+
+
    }
+
+
+
+ 340 +
+
+ 29640 +
+
+
}
+
+
+
+ 341 +
+
+ +
+
+

+            
+
+
+ 342 +
+
+ +
+
+
/**
+
+
+
+ 343 +
+
+ +
+
+
 * Remove constant bools from and expressions
+
+
+
+ 344 +
+
+ +
+
+
 * ```text
+
+
+
+ 345 +
+
+ +
+
+
 * and([true, a]) = a
+
+
+
+ 346 +
+
+ 1 +
+
+
 * and([false, a]) = false
+
+
+
+ 347 +
+
+ 1 +
+
+
 * ```
+
+
+
+ 348 +
+
+ 1 +
+
+
 */
+
+
+
+ 349 +
+
+ +
+
+
#[register_rule(("Base", 100))]
+
+
+
+ 350 +
+
+ 29640 +
+
+
fn remove_constants_from_and(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 351 +
+
+ 29640 +
+
+
    match expr {
+
+
+
+ 352 +
+
+ 1560 +
+
+
        Expr::And(metadata, exprs) => {
+
+
+
+ 353 +
+
+ 1560 +
+
+
            let mut new_exprs = Vec::new();
+
+
+
+ 354 +
+
+ 1560 +
+
+
            let mut changed = false;
+
+
+
+ 355 +
+
+ 9465 +
+
+
            for e in exprs {
+
+
+
+ 356 +
+
+ 30 +
+
+
                match e {
+
+
+
+ 357 +
+
+ 30 +
+
+
                    Expr::Constant(metadata, Const::Bool(val)) => {
+
+
+
+ 358 +
+
+ 30 +
+
+
                        if !*val {
+
+
+
+ 359 +
+
+ +
+
+
                            // If we find a false, the whole expression is false
+
+
+
+ 360 +
+
+ 15 +
+
+
                            return Ok(Reduction::pure(Expr::Constant(
+
+
+
+ 361 +
+
+ 15 +
+
+
                                metadata.clone(),
+
+
+
+ 362 +
+
+ 15 +
+
+
                                Const::Bool(false),
+
+
+
+ 363 +
+
+ 15 +
+
+
                            )));
+
+
+
+ 364 +
+
+ 15 +
+
+
                        } else {
+
+
+
+ 365 +
+
+ 15 +
+
+
                            // If we find a true, we can ignore it
+
+
+
+ 366 +
+
+ 15 +
+
+
                            changed = true;
+
+
+
+ 367 +
+
+ 15 +
+
+
                        }
+
+
+
+ 368 +
+
+ +
+
+
                    }
+
+
+
+ 369 +
+
+ 7890 +
+
+
                    _ => new_exprs.push(e.clone()),
+
+
+
+ 370 +
+
+ +
+
+
                }
+
+
+
+ 371 +
+
+ +
+
+
            }
+
+
+
+ 372 +
+
+ 1545 +
+
+
            if !changed {
+
+
+
+ 373 +
+
+ 1545 +
+
+
                return Err(ApplicationError::RuleNotApplicable);
+
+
+
+ 374 +
+
+ +
+
+
            }
+
+
+
+ 375 +
+
+ +
+
+
            Ok(Reduction::pure(Expr::And(metadata.clone(), new_exprs)))
+
+
+
+ 376 +
+
+ +
+
+
        }
+
+
+
+ 377 +
+
+ 28080 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 378 +
+
+ +
+
+
    }
+
+
+
+ 379 +
+
+ 29640 +
+
+
}
+
+
+
+ 380 +
+
+ +
+
+

+            
+
+
+ 381 +
+
+ +
+
+
/**
+
+
+
+ 382 +
+
+ +
+
+
 * Evaluate Not expressions with constant bools
+
+
+
+ 383 +
+
+ +
+
+
 * ```text
+
+
+
+ 384 +
+
+ +
+
+
 * not(true) = false
+
+
+
+ 385 +
+
+ 1 +
+
+
 * not(false) = true
+
+
+
+ 386 +
+
+ 1 +
+
+
 * ```
+
+
+
+ 387 +
+
+ 1 +
+
+
 */
+
+
+
+ 388 +
+
+ +
+
+
#[register_rule(("Base", 100))]
+
+
+
+ 389 +
+
+ 29610 +
+
+
fn evaluate_constant_not(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 390 +
+
+ 29610 +
+
+
    match expr {
+
+
+
+ 391 +
+
+ +
+
+
        Expr::Not(_, contents) => match contents.as_ref() {
+
+
+
+ 392 +
+
+ +
+
+
            Expr::Constant(metadata, Const::Bool(val)) => Ok(Reduction::pure(Expr::Constant(
+
+
+
+ 393 +
+
+ +
+
+
                metadata.clone(),
+
+
+
+ 394 +
+
+ +
+
+
                Const::Bool(!val),
+
+
+
+ 395 +
+
+ +
+
+
            ))),
+
+
+
+ 396 +
+
+ +
+
+
            _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 397 +
+
+ +
+
+
        },
+
+
+
+ 398 +
+
+ 29610 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 399 +
+
+ +
+
+
    }
+
+
+
+ 400 +
+
+ 29610 +
+
+
}
+
+
+
+ 401 +
+
+ +
+
+

+            
+
+
+ 402 +
+
+ +
+
+
// /** Turn a Div into a SafeDiv and post a global constraint to avoid undefined. */
+
+
+
+ 403 +
+
+ +
+
+
// #[register_rule(("Base", 100))]
+
+
+
+ 404 +
+
+ +
+
+
// fn ensure_div(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 405 +
+
+ +
+
+
//     match expr {
+
+
+
+ 406 +
+
+ +
+
+
//         Expr::Div(metadata, a, b) => Ok(Reduction::with_top(
+
+
+
+ 407 +
+
+ +
+
+
//             Expr::SafeDiv(metadata.clone(), a.clone(), b.clone()),
+
+
+
+ 408 +
+
+ +
+
+
//             Expr::Neq(
+
+
+
+ 409 +
+
+ +
+
+
//                 Metadata::new(),
+
+
+
+ 410 +
+
+ +
+
+
//                 b.clone(),
+
+
+
+ 411 +
+
+ +
+
+
//                 Box::new(Expr::Constant(Metadata::new(), Const::Int(0))),
+
+
+
+ 412 +
+
+ +
+
+
//             ),
+
+
+
+ 413 +
+
+ +
+
+
//         )),
+
+
+
+ 414 +
+
+ +
+
+
//         _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 415 +
+
+ +
+
+
//     }
+
+
+
+ 416 +
+
+ +
+
+
// }
+
+
+
+ 417 +
+
+ +
+
+

+            
+
+
+ 418 +
+
+ +
+
+
/**
+
+
+
+ 419 +
+
+ +
+
+
 * Turn a Min into a new variable and post a global constraint to ensure the new variable is the minimum.
+
+
+
+ 420 +
+
+ +
+
+
 * ```text
+
+
+
+ 421 +
+
+ 1 +
+
+
 * min([a, b]) ~> c ; c <= a & c <= b & (c = a | c = b)
+
+
+
+ 422 +
+
+ 1 +
+
+
 * ```
+
+
+
+ 423 +
+
+ 1 +
+
+
 */
+
+
+
+ 424 +
+
+ +
+
+
#[register_rule(("Base", 100))]
+
+
+
+ 425 +
+
+ 29610 +
+
+
fn min_to_var(expr: &Expr, mdl: &Model) -> ApplicationResult {
+
+
+
+ 426 +
+
+ 29610 +
+
+
    match expr {
+
+
+
+ 427 +
+
+ 75 +
+
+
        Expr::Min(metadata, exprs) => {
+
+
+
+ 428 +
+
+ 75 +
+
+
            let new_name = mdl.gensym();
+
+
+
+ 429 +
+
+ 75 +
+
+

+            
+
+
+ 430 +
+
+ 75 +
+
+
            let mut new_top = Vec::new(); // the new variable must be less than or equal to all the other variables
+
+
+
+ 431 +
+
+ 75 +
+
+
            let mut disjunction = Vec::new(); // the new variable must be equal to one of the variables
+
+
+
+ 432 +
+
+ 225 +
+
+
            for e in exprs {
+
+
+
+ 433 +
+
+ 150 +
+
+
                new_top.push(Expr::Leq(
+
+
+
+ 434 +
+
+ 150 +
+
+
                    Metadata::new(),
+
+
+
+ 435 +
+
+ 150 +
+
+
                    Box::new(Expr::Reference(Metadata::new(), new_name.clone())),
+
+
+
+ 436 +
+
+ 150 +
+
+
                    Box::new(e.clone()),
+
+
+
+ 437 +
+
+ 150 +
+
+
                ));
+
+
+
+ 438 +
+
+ 150 +
+
+
                disjunction.push(Expr::And(
+
+
+
+ 439 +
+
+ 150 +
+
+
                    // TODO: change to an Eq once we figure out how to apply them later
+
+
+
+ 440 +
+
+ 150 +
+
+
                    Metadata::new(),
+
+
+
+ 441 +
+
+ 150 +
+
+
                    vec![
+
+
+
+ 442 +
+
+ 150 +
+
+
                        Expr::Leq(
+
+
+
+ 443 +
+
+ 150 +
+
+
                            Metadata::new(),
+
+
+
+ 444 +
+
+ 150 +
+
+
                            Box::new(Expr::Reference(Metadata::new(), new_name.clone())),
+
+
+
+ 445 +
+
+ 150 +
+
+
                            Box::new(e.clone()),
+
+
+
+ 446 +
+
+ 150 +
+
+
                        ),
+
+
+
+ 447 +
+
+ 150 +
+
+
                        Expr::Geq(
+
+
+
+ 448 +
+
+ 150 +
+
+
                            Metadata::new(),
+
+
+
+ 449 +
+
+ 150 +
+
+
                            Box::new(Expr::Reference(Metadata::new(), new_name.clone())),
+
+
+
+ 450 +
+
+ 150 +
+
+
                            Box::new(e.clone()),
+
+
+
+ 451 +
+
+ 150 +
+
+
                        ),
+
+
+
+ 452 +
+
+ 150 +
+
+
                    ],
+
+
+
+ 453 +
+
+ 150 +
+
+
                ));
+
+
+
+ 454 +
+
+ 150 +
+
+
            }
+
+
+
+ 455 +
+
+ 75 +
+
+
            new_top.push(Expr::Or(Metadata::new(), disjunction));
+
+
+
+ 456 +
+
+ 75 +
+
+

+            
+
+
+ 457 +
+
+ 75 +
+
+
            let mut new_vars = SymbolTable::new();
+
+
+
+ 458 +
+
+ 75 +
+
+
            let bound = expr
+
+
+
+ 459 +
+
+ 75 +
+
+
                .bounds(&mdl.variables)
+
+
+
+ 460 +
+
+ 75 +
+
+
                .ok_or(ApplicationError::BoundError)?;
+
+
+
+ 461 +
+
+ 75 +
+
+
            new_vars.insert(
+
+
+
+ 462 +
+
+ 75 +
+
+
                new_name.clone(),
+
+
+
+ 463 +
+
+ 75 +
+
+
                DecisionVariable::new(Domain::IntDomain(vec![Range::Bounded(bound.0, bound.1)])),
+
+
+
+ 464 +
+
+ 75 +
+
+
            );
+
+
+
+ 465 +
+
+ 75 +
+
+

+            
+
+
+ 466 +
+
+ 75 +
+
+
            Ok(Reduction::new(
+
+
+
+ 467 +
+
+ 75 +
+
+
                Expr::Reference(Metadata::new(), new_name),
+
+
+
+ 468 +
+
+ 75 +
+
+
                Expr::And(metadata.clone(), new_top),
+
+
+
+ 469 +
+
+ 75 +
+
+
                new_vars,
+
+
+
+ 470 +
+
+ 75 +
+
+
            ))
+
+
+
+ 471 +
+
+ +
+
+
        }
+
+
+
+ 472 +
+
+ 29535 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 473 +
+
+ +
+
+
    }
+
+
+
+ 474 +
+
+ 29610 +
+
+
}
+
+
+
+ 475 +
+
+ +
+
+

+            
+
+
+ 476 +
+
+ +
+
+
/**
+
+
+
+ 477 +
+
+ +
+
+
* Apply the Distributive Law to expressions like `Or([..., And(a, b)])`
+
+
+
+ 478 +
+
+ +
+
+

+            
+
+
+ 479 +
+
+ +
+
+
* ```text
+
+
+
+ 480 +
+
+ 1 +
+
+
* or(and(a, b), c) = and(or(a, c), or(b, c))
+
+
+
+ 481 +
+
+ 1 +
+
+
* ```
+
+
+
+ 482 +
+
+ 1 +
+
+
 */
+
+
+
+ 483 +
+
+ +
+
+
#[register_rule(("Base", 100))]
+
+
+
+ 484 +
+
+ 29625 +
+
+
fn distribute_or_over_and(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 485 +
+
+ 29625 +
+
+
    fn find_and(exprs: &[Expr]) -> Option<usize> {
+
+
+
+ 486 +
+
+ 29625 +
+
+
        // ToDo: may be better to move this to some kind of utils module?
+
+
+
+ 487 +
+
+ 29625 +
+
+
        for (i, e) in exprs.iter().enumerate() {
+
+
+
+ 488 +
+
+ 29625 +
+
+
            if let Expr::And(_, _) = e {
+
+
+
+ 489 +
+
+ 29625 +
+
+
                return Some(i);
+
+
+
+ 490 +
+
+ 29625 +
+
+
            }
+
+
+
+ 491 +
+
+ 29625 +
+
+
        }
+
+
+
+ 492 +
+
+ 29625 +
+
+
        None
+
+
+
+ 493 +
+
+ 29625 +
+
+
    }
+
+
+
+ 494 +
+
+ 29625 +
+
+

+            
+
+
+ 495 +
+
+ 29625 +
+
+
    match expr {
+
+
+
+ 496 +
+
+ 2190 +
+
+
        Expr::Or(_, exprs) => match find_and(exprs) {
+
+
+
+ 497 +
+
+ 240 +
+
+
            Some(idx) => {
+
+
+
+ 498 +
+
+ 240 +
+
+
                let mut rest = exprs.clone();
+
+
+
+ 499 +
+
+ 240 +
+
+
                let and_expr = rest.remove(idx);
+
+
+
+ 500 +
+
+ 240 +
+
+

+            
+
+
+ 501 +
+
+ 240 +
+
+
                match and_expr {
+
+
+
+ 502 +
+
+ 240 +
+
+
                    Expr::And(metadata, and_exprs) => {
+
+
+
+ 503 +
+
+ 240 +
+
+
                        let mut new_and_contents = Vec::new();
+
+
+
+ 504 +
+
+ +
+
+

+            
+
+
+ 505 +
+
+ 720 +
+
+
                        for e in and_exprs {
+
+
+
+ 506 +
+
+ +
+
+
                            // ToDo: Cloning everything may be a bit inefficient - discuss
+
+
+
+ 507 +
+
+ 480 +
+
+
                            let mut new_or_contents = rest.clone();
+
+
+
+ 508 +
+
+ 480 +
+
+
                            new_or_contents.push(e.clone());
+
+
+
+ 509 +
+
+ 480 +
+
+
                            new_and_contents.push(Expr::Or(metadata.clone(), new_or_contents))
+
+
+
+ 510 +
+
+ +
+
+
                        }
+
+
+
+ 511 +
+
+ +
+
+

+            
+
+
+ 512 +
+
+ 240 +
+
+
                        Ok(Reduction::pure(Expr::And(
+
+
+
+ 513 +
+
+ 240 +
+
+
                            metadata.clone(),
+
+
+
+ 514 +
+
+ 240 +
+
+
                            new_and_contents,
+
+
+
+ 515 +
+
+ 240 +
+
+
                        )))
+
+
+
+ 516 +
+
+ +
+
+
                    }
+
+
+
+ 517 +
+
+ +
+
+
                    _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 518 +
+
+ +
+
+
                }
+
+
+
+ 519 +
+
+ +
+
+
            }
+
+
+
+ 520 +
+
+ 1950 +
+
+
            None => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 521 +
+
+ +
+
+
        },
+
+
+
+ 522 +
+
+ 27435 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 523 +
+
+ +
+
+
    }
+
+
+
+ 524 +
+
+ 29625 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rules/cnf.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rules/cnf.rs.html new file mode 100644 index 0000000000..fbfa081712 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rules/cnf.rs.html @@ -0,0 +1,1001 @@ + + + + + Grcov report - cnf.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
/***********************************************************************************/
+
+
+
+ 2 +
+
+ +
+
+
/*        This file contains rules for converting logic expressions to CNF         */
+
+
+
+ 3 +
+
+ +
+
+
/***********************************************************************************/
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ +
+
+
use conjure_core::ast::Expression as Expr;
+
+
+
+ 6 +
+
+ +
+
+
use conjure_core::rule_engine::{
+
+
+
+ 7 +
+
+ +
+
+
    register_rule, register_rule_set, ApplicationError, ApplicationResult, Reduction,
+
+
+
+ 8 +
+
+ +
+
+
};
+
+
+
+ 9 +
+
+ +
+
+
use conjure_core::solver::SolverFamily;
+
+
+
+ 10 +
+
+ +
+
+
use conjure_core::Model;
+
+
+
+ 11 +
+
+ +
+
+

+            
+
+
+ 12 +
+
+ +
+
+
register_rule_set!("CNF", 100, ("Base"), (SolverFamily::SAT));
+
+
+
+ 13 +
+
+ +
+
+

+            
+
+
+ 14 +
+
+ +
+
+
/**
+
+
+
+ 15 +
+
+ +
+
+
* Distribute `not` over `and` (De Morgan's Law):
+
+
+
+ 16 +
+
+ +
+
+

+            
+
+
+ 17 +
+
+ +
+
+
* ```text
+
+
+
+ 18 +
+
+ 1 +
+
+
* not(and(a, b)) = or(not a, not b)
+
+
+
+ 19 +
+
+ 1 +
+
+
* ```
+
+
+
+ 20 +
+
+ 1 +
+
+
 */
+
+
+
+ 21 +
+
+ +
+
+
#[register_rule(("CNF", 100))]
+
+
+
+ 22 +
+
+ 255 +
+
+
fn distribute_not_over_and(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 23 +
+
+ 255 +
+
+
    match expr {
+
+
+
+ 24 +
+
+ 30 +
+
+
        Expr::Not(_, contents) => match contents.as_ref() {
+
+
+
+ 25 +
+
+ 15 +
+
+
            Expr::And(metadata, exprs) => {
+
+
+
+ 26 +
+
+ 15 +
+
+
                let mut new_exprs = Vec::new();
+
+
+
+ 27 +
+
+ 45 +
+
+
                for e in exprs {
+
+
+
+ 28 +
+
+ 30 +
+
+
                    new_exprs.push(Expr::Not(metadata.clone(), Box::new(e.clone())));
+
+
+
+ 29 +
+
+ 30 +
+
+
                }
+
+
+
+ 30 +
+
+ 15 +
+
+
                Ok(Reduction::pure(Expr::Or(metadata.clone(), new_exprs)))
+
+
+
+ 31 +
+
+ +
+
+
            }
+
+
+
+ 32 +
+
+ 15 +
+
+
            _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 33 +
+
+ +
+
+
        },
+
+
+
+ 34 +
+
+ 225 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 35 +
+
+ +
+
+
    }
+
+
+
+ 36 +
+
+ 255 +
+
+
}
+
+
+
+ 37 +
+
+ +
+
+

+            
+
+
+ 38 +
+
+ +
+
+
/**
+
+
+
+ 39 +
+
+ +
+
+
* Distribute `not` over `or` (De Morgan's Law):
+
+
+
+ 40 +
+
+ +
+
+

+            
+
+
+ 41 +
+
+ +
+
+
* ```text
+
+
+
+ 42 +
+
+ 1 +
+
+
* not(or(a, b)) = and(not a, not b)
+
+
+
+ 43 +
+
+ 1 +
+
+
* ```
+
+
+
+ 44 +
+
+ 1 +
+
+
 */
+
+
+
+ 45 +
+
+ +
+
+
#[register_rule(("CNF", 100))]
+
+
+
+ 46 +
+
+ 255 +
+
+
fn distribute_not_over_or(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 47 +
+
+ 255 +
+
+
    match expr {
+
+
+
+ 48 +
+
+ 30 +
+
+
        Expr::Not(_, contents) => match contents.as_ref() {
+
+
+
+ 49 +
+
+ 15 +
+
+
            Expr::Or(metadata, exprs) => {
+
+
+
+ 50 +
+
+ 15 +
+
+
                let mut new_exprs = Vec::new();
+
+
+
+ 51 +
+
+ 45 +
+
+
                for e in exprs {
+
+
+
+ 52 +
+
+ 30 +
+
+
                    new_exprs.push(Expr::Not(metadata.clone(), Box::new(e.clone())));
+
+
+
+ 53 +
+
+ 30 +
+
+
                }
+
+
+
+ 54 +
+
+ 15 +
+
+
                Ok(Reduction::pure(Expr::And(metadata.clone(), new_exprs)))
+
+
+
+ 55 +
+
+ +
+
+
            }
+
+
+
+ 56 +
+
+ 15 +
+
+
            _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 57 +
+
+ +
+
+
        },
+
+
+
+ 58 +
+
+ 225 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 59 +
+
+ +
+
+
    }
+
+
+
+ 60 +
+
+ 255 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rules/constant.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rules/constant.rs.html new file mode 100644 index 0000000000..4566450487 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rules/constant.rs.html @@ -0,0 +1,2041 @@ + + + + + Grcov report - constant.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use conjure_core::ast::{Constant as Const, Expression as Expr};
+
+
+
+ 2 +
+
+ +
+
+
use conjure_core::metadata::Metadata;
+
+
+
+ 3 +
+
+ +
+
+
use conjure_core::rule_engine::{
+
+
+
+ 4 +
+
+ +
+
+
    register_rule, register_rule_set, ApplicationError, ApplicationResult, Reduction,
+
+
+
+ 5 +
+
+ +
+
+
};
+
+
+
+ 6 +
+
+ +
+
+
use conjure_core::Model;
+
+
+
+ 7 +
+
+ +
+
+

+            
+
+
+ 8 +
+
+ +
+
+
register_rule_set!("Constant", 255, ());
+
+
+
+ 9 +
+
+ +
+
+

+            
+
+
+ 10 +
+
+ +
+
+
#[register_rule(("Constant", 255))]
+
+
+
+ 11 +
+
+ 29610 +
+
+
fn apply_eval_constant(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 12 +
+
+ 29610 +
+
+
    if expr.is_constant() {
+
+
+
+ 13 +
+
+ 7200 +
+
+
        return Err(ApplicationError::RuleNotApplicable);
+
+
+
+ 14 +
+
+ 22410 +
+
+
    }
+
+
+
+ 15 +
+
+ 22410 +
+
+
    eval_constant(expr)
+
+
+
+ 16 +
+
+ 22410 +
+
+
        .map(|c| Reduction::pure(Expr::Constant(Metadata::new(), c)))
+
+
+
+ 17 +
+
+ 22410 +
+
+
        .ok_or(ApplicationError::RuleNotApplicable)
+
+
+
+ 18 +
+
+ 29610 +
+
+
}
+
+
+
+ 19 +
+
+ +
+
+

+            
+
+
+ 20 +
+
+ +
+
+
/// Simplify an expression to a constant if possible
+
+
+
+ 21 +
+
+ +
+
+
/// Returns:
+
+
+
+ 22 +
+
+ +
+
+
/// `None` if the expression cannot be simplified to a constant (e.g. if it contains a variable)
+
+
+
+ 23 +
+
+ +
+
+
/// `Some(Const)` if the expression can be simplified to a constant
+
+
+
+ 24 +
+
+ 39255 +
+
+
pub fn eval_constant(expr: &Expr) -> Option<Const> {
+
+
+
+ 25 +
+
+ 39255 +
+
+
    match expr {
+
+
+
+ 26 +
+
+ 1260 +
+
+
        Expr::Constant(_, c) => Some(c.clone()),
+
+
+
+ 27 +
+
+ 22440 +
+
+
        Expr::Reference(_, _) => None,
+
+
+
+ 28 +
+
+ 150 +
+
+
        Expr::Eq(_, a, b) => bin_op::<i32, bool>(|a, b| a == b, a, b)
+
+
+
+ 29 +
+
+ 150 +
+
+
            .or_else(|| bin_op::<bool, bool>(|a, b| a == b, a, b))
+
+
+
+ 30 +
+
+ 150 +
+
+
            .map(Const::Bool),
+
+
+
+ 31 +
+
+ 30 +
+
+
        Expr::Neq(_, a, b) => bin_op::<i32, bool>(|a, b| a != b, a, b).map(Const::Bool),
+
+
+
+ 32 +
+
+ 15 +
+
+
        Expr::Lt(_, a, b) => bin_op::<i32, bool>(|a, b| a < b, a, b).map(Const::Bool),
+
+
+
+ 33 +
+
+ +
+
+
        Expr::Gt(_, a, b) => bin_op::<i32, bool>(|a, b| a > b, a, b).map(Const::Bool),
+
+
+
+ 34 +
+
+ 870 +
+
+
        Expr::Leq(_, a, b) => bin_op::<i32, bool>(|a, b| a <= b, a, b).map(Const::Bool),
+
+
+
+ 35 +
+
+ 495 +
+
+
        Expr::Geq(_, a, b) => bin_op::<i32, bool>(|a, b| a >= b, a, b).map(Const::Bool),
+
+
+
+ 36 +
+
+ +
+
+

+            
+
+
+ 37 +
+
+ +
+
+
        Expr::Not(_, expr) => un_op::<bool, bool>(|e| !e, expr).map(Const::Bool),
+
+
+
+ 38 +
+
+ +
+
+

+            
+
+
+ 39 +
+
+ 1830 +
+
+
        Expr::And(_, exprs) => {
+
+
+
+ 40 +
+
+ 1830 +
+
+
            vec_op::<bool, bool>(|e| e.iter().all(|&e| e), exprs).map(Const::Bool)
+
+
+
+ 41 +
+
+ +
+
+
        }
+
+
+
+ 42 +
+
+ 2190 +
+
+
        Expr::Or(_, exprs) => {
+
+
+
+ 43 +
+
+ 2190 +
+
+
            vec_op::<bool, bool>(|e| e.iter().any(|&e| e), exprs).map(Const::Bool)
+
+
+
+ 44 +
+
+ +
+
+
        }
+
+
+
+ 45 +
+
+ +
+
+

+            
+
+
+ 46 +
+
+ 330 +
+
+
        Expr::Sum(_, exprs) => vec_op::<i32, i32>(|e| e.iter().sum(), exprs).map(Const::Int),
+
+
+
+ 47 +
+
+ +
+
+

+            
+
+
+ 48 +
+
+ 9045 +
+
+
        Expr::Ineq(_, a, b, c) => {
+
+
+
+ 49 +
+
+ 9045 +
+
+
            tern_op::<i32, bool>(|a, b, c| a <= (b + c), a, b, c).map(Const::Bool)
+
+
+
+ 50 +
+
+ +
+
+
        }
+
+
+
+ 51 +
+
+ +
+
+

+            
+
+
+ 52 +
+
+ 180 +
+
+
        Expr::SumGeq(_, exprs, a) => {
+
+
+
+ 53 +
+
+ 180 +
+
+
            flat_op::<i32, bool>(|e, a| e.iter().sum::<i32>() >= a, exprs, a).map(Const::Bool)
+
+
+
+ 54 +
+
+ +
+
+
        }
+
+
+
+ 55 +
+
+ 75 +
+
+
        Expr::SumLeq(_, exprs, a) => {
+
+
+
+ 56 +
+
+ 75 +
+
+
            flat_op::<i32, bool>(|e, a| e.iter().sum::<i32>() <= a, exprs, a).map(Const::Bool)
+
+
+
+ 57 +
+
+ +
+
+
        }
+
+
+
+ 58 +
+
+ +
+
+
        // Expr::Div(_, a, b) => bin_op::<i32, i32>(|a, b| a / b, a, b).map(Const::Int),
+
+
+
+ 59 +
+
+ +
+
+
        // Expr::SafeDiv(_, a, b) => bin_op::<i32, i32>(|a, b| a / b, a, b).map(Const::Int),
+
+
+
+ 60 +
+
+ 225 +
+
+
        Expr::Min(_, exprs) => {
+
+
+
+ 61 +
+
+ 225 +
+
+
            opt_vec_op::<i32, i32>(|e| e.iter().min().copied(), exprs).map(Const::Int)
+
+
+
+ 62 +
+
+ +
+
+
        }
+
+
+
+ 63 +
+
+ +
+
+
        _ => {
+
+
+
+ 64 +
+
+ 120 +
+
+
            println!("WARNING: Unimplemented constant eval: {:?}", expr);
+
+
+
+ 65 +
+
+ 120 +
+
+
            None
+
+
+
+ 66 +
+
+ +
+
+
        }
+
+
+
+ 67 +
+
+ +
+
+
    }
+
+
+
+ 68 +
+
+ 39255 +
+
+
}
+
+
+
+ 69 +
+
+ +
+
+

+            
+
+
+ 70 +
+
+ +
+
+
fn un_op<T, A>(f: fn(T) -> A, a: &Expr) -> Option<A>
+
+
+
+ 71 +
+
+ +
+
+
where
+
+
+
+ 72 +
+
+ +
+
+
    T: TryFrom<Const>,
+
+
+
+ 73 +
+
+ +
+
+
{
+
+
+
+ 74 +
+
+ +
+
+
    let a = unwrap_expr::<T>(a)?;
+
+
+
+ 75 +
+
+ +
+
+
    Some(f(a))
+
+
+
+ 76 +
+
+ +
+
+
}
+
+
+
+ 77 +
+
+ +
+
+

+            
+
+
+ 78 +
+
+ 1695 +
+
+
fn bin_op<T, A>(f: fn(T, T) -> A, a: &Expr, b: &Expr) -> Option<A>
+
+
+
+ 79 +
+
+ 1695 +
+
+
where
+
+
+
+ 80 +
+
+ 1695 +
+
+
    T: TryFrom<Const>,
+
+
+
+ 81 +
+
+ 1695 +
+
+
{
+
+
+
+ 82 +
+
+ 1695 +
+
+
    let a = unwrap_expr::<T>(a)?;
+
+
+
+ 83 +
+
+ 45 +
+
+
    let b = unwrap_expr::<T>(b)?;
+
+
+
+ 84 +
+
+ 30 +
+
+
    Some(f(a, b))
+
+
+
+ 85 +
+
+ 1695 +
+
+
}
+
+
+
+ 86 +
+
+ +
+
+

+            
+
+
+ 87 +
+
+ 9045 +
+
+
fn tern_op<T, A>(f: fn(T, T, T) -> A, a: &Expr, b: &Expr, c: &Expr) -> Option<A>
+
+
+
+ 88 +
+
+ 9045 +
+
+
where
+
+
+
+ 89 +
+
+ 9045 +
+
+
    T: TryFrom<Const>,
+
+
+
+ 90 +
+
+ 9045 +
+
+
{
+
+
+
+ 91 +
+
+ 9045 +
+
+
    let a = unwrap_expr::<T>(a)?;
+
+
+
+ 92 +
+
+ 990 +
+
+
    let b = unwrap_expr::<T>(b)?;
+
+
+
+ 93 +
+
+ +
+
+
    let c = unwrap_expr::<T>(c)?;
+
+
+
+ 94 +
+
+ +
+
+
    Some(f(a, b, c))
+
+
+
+ 95 +
+
+ 9045 +
+
+
}
+
+
+
+ 96 +
+
+ +
+
+

+            
+
+
+ 97 +
+
+ 4350 +
+
+
fn vec_op<T, A>(f: fn(Vec<T>) -> A, a: &[Expr]) -> Option<A>
+
+
+
+ 98 +
+
+ 4350 +
+
+
where
+
+
+
+ 99 +
+
+ 4350 +
+
+
    T: TryFrom<Const>,
+
+
+
+ 100 +
+
+ 4350 +
+
+
{
+
+
+
+ 101 +
+
+ 4350 +
+
+
    let a = a.iter().map(unwrap_expr).collect::<Option<Vec<T>>>()?;
+
+
+
+ 102 +
+
+ 30 +
+
+
    Some(f(a))
+
+
+
+ 103 +
+
+ 4350 +
+
+
}
+
+
+
+ 104 +
+
+ +
+
+

+            
+
+
+ 105 +
+
+ 225 +
+
+
fn opt_vec_op<T, A>(f: fn(Vec<T>) -> Option<A>, a: &[Expr]) -> Option<A>
+
+
+
+ 106 +
+
+ 225 +
+
+
where
+
+
+
+ 107 +
+
+ 225 +
+
+
    T: TryFrom<Const>,
+
+
+
+ 108 +
+
+ 225 +
+
+
{
+
+
+
+ 109 +
+
+ 225 +
+
+
    let a = a.iter().map(unwrap_expr).collect::<Option<Vec<T>>>()?;
+
+
+
+ 110 +
+
+ +
+
+
    f(a)
+
+
+
+ 111 +
+
+ 225 +
+
+
}
+
+
+
+ 112 +
+
+ +
+
+

+            
+
+
+ 113 +
+
+ 255 +
+
+
fn flat_op<T, A>(f: fn(Vec<T>, T) -> A, a: &[Expr], b: &Expr) -> Option<A>
+
+
+
+ 114 +
+
+ 255 +
+
+
where
+
+
+
+ 115 +
+
+ 255 +
+
+
    T: TryFrom<Const>,
+
+
+
+ 116 +
+
+ 255 +
+
+
{
+
+
+
+ 117 +
+
+ 255 +
+
+
    let a = a.iter().map(unwrap_expr).collect::<Option<Vec<T>>>()?;
+
+
+
+ 118 +
+
+ +
+
+
    let b = unwrap_expr::<T>(b)?;
+
+
+
+ 119 +
+
+ +
+
+
    Some(f(a, b))
+
+
+
+ 120 +
+
+ 255 +
+
+
}
+
+
+
+ 121 +
+
+ +
+
+

+            
+
+
+ 122 +
+
+ 16680 +
+
+
fn unwrap_expr<T: TryFrom<Const>>(expr: &Expr) -> Option<T> {
+
+
+
+ 123 +
+
+ 16680 +
+
+
    let c = eval_constant(expr)?;
+
+
+
+ 124 +
+
+ 1230 +
+
+
    TryInto::<T>::try_into(c).ok()
+
+
+
+ 125 +
+
+ 16680 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rules/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rules/index.html new file mode 100644 index 0000000000..6908dcd64e --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rules/index.html @@ -0,0 +1,146 @@ + + + + + Grcov report - crates/conjure_core/src/rules + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
base.rs + + 82.72% + + + 82.72% + + 292 / 353 + 15.42%33 / 214
cnf.rs + + 90.91% + + + 90.91% + + 30 / 33 + 13.89%5 / 36
constant.rs + + 82.02% + + + 82.02% + + 73 / 89 + 16.22%18 / 111
minion.rs + + 86.5% + + + 86.5% + + 141 / 163 + 15.17%22 / 145
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rules/minion.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rules/minion.rs.html new file mode 100644 index 0000000000..c1eb081c99 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/rules/minion.rs.html @@ -0,0 +1,4793 @@ + + + + + Grcov report - minion.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
/************************************************************************/
+
+
+
+ 2 +
+
+ +
+
+
/*        Rules for translating to Minion-supported constraints         */
+
+
+
+ 3 +
+
+ +
+
+
/************************************************************************/
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ +
+
+
use crate::ast::{Constant as Const, Expression as Expr};
+
+
+
+ 6 +
+
+ +
+
+
use crate::metadata::Metadata;
+
+
+
+ 7 +
+
+ +
+
+
use crate::rule_engine::{
+
+
+
+ 8 +
+
+ +
+
+
    register_rule, register_rule_set, ApplicationError, ApplicationResult, Reduction,
+
+
+
+ 9 +
+
+ +
+
+
};
+
+
+
+ 10 +
+
+ +
+
+
use crate::solver::SolverFamily;
+
+
+
+ 11 +
+
+ +
+
+
use crate::Model;
+
+
+
+ 12 +
+
+ +
+
+

+            
+
+
+ 13 +
+
+ +
+
+
register_rule_set!("Minion", 100, ("Base"), (SolverFamily::Minion));
+
+
+
+ 14 +
+
+ +
+
+

+            
+
+
+ 15 +
+
+ 120 +
+
+
fn is_nested_sum(exprs: &Vec<Expr>) -> bool {
+
+
+
+ 16 +
+
+ 375 +
+
+
    for e in exprs {
+
+
+
+ 17 +
+
+ 285 +
+
+
        if let Expr::Sum(_, _) = e {
+
+
+
+ 18 +
+
+ 30 +
+
+
            return true;
+
+
+
+ 19 +
+
+ 255 +
+
+
        }
+
+
+
+ 20 +
+
+ +
+
+
    }
+
+
+
+ 21 +
+
+ 90 +
+
+
    false
+
+
+
+ 22 +
+
+ 120 +
+
+
}
+
+
+
+ 23 +
+
+ +
+
+

+            
+
+
+ 24 +
+
+ +
+
+
/**
+
+
+
+ 25 +
+
+ +
+
+
 * Helper function to get the vector of expressions from a sum (or error if it's a nested sum - we need to flatten it first)
+
+
+
+ 26 +
+
+ +
+
+
 */
+
+
+
+ 27 +
+
+ 975 +
+
+
fn sum_to_vector(expr: &Expr) -> Result<Vec<Expr>, ApplicationError> {
+
+
+
+ 28 +
+
+ 975 +
+
+
    match expr {
+
+
+
+ 29 +
+
+ 120 +
+
+
        Expr::Sum(_, exprs) => {
+
+
+
+ 30 +
+
+ 120 +
+
+
            if is_nested_sum(exprs) {
+
+
+
+ 31 +
+
+ 30 +
+
+
                Err(ApplicationError::RuleNotApplicable)
+
+
+
+ 32 +
+
+ +
+
+
            } else {
+
+
+
+ 33 +
+
+ 90 +
+
+
                Ok(exprs.clone())
+
+
+
+ 34 +
+
+ +
+
+
            }
+
+
+
+ 35 +
+
+ +
+
+
        }
+
+
+
+ 36 +
+
+ 855 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 37 +
+
+ +
+
+
    }
+
+
+
+ 38 +
+
+ 975 +
+
+
}
+
+
+
+ 39 +
+
+ +
+
+

+            
+
+
+ 40 +
+
+ +
+
+
// /**
+
+
+
+ 41 +
+
+ +
+
+
//  * Convert an Eq to a conjunction of Geq and Leq:
+
+
+
+ 42 +
+
+ +
+
+
//  * ```text
+
+
+
+ 43 +
+
+ +
+
+
//  * a = b => a >= b && a <= b
+
+
+
+ 44 +
+
+ +
+
+
//  * ```
+
+
+
+ 45 +
+
+ +
+
+
//  */
+
+
+
+ 46 +
+
+ +
+
+
// #[register_rule(("Minion", 100))]
+
+
+
+ 47 +
+
+ +
+
+
// fn eq_to_minion(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 48 +
+
+ +
+
+
//     match expr {
+
+
+
+ 49 +
+
+ +
+
+
//         Expr::Eq(metadata, a, b) => Ok(Reduction::pure(Expr::And(
+
+
+
+ 50 +
+
+ +
+
+
//             metadata.clone(),
+
+
+
+ 51 +
+
+ +
+
+
//             vec![
+
+
+
+ 52 +
+
+ +
+
+
//                 Expr::Geq(metadata.clone(), a.clone(), b.clone()),
+
+
+
+ 53 +
+
+ +
+
+
//                 Expr::Leq(metadata.clone(), a.clone(), b.clone()),
+
+
+
+ 54 +
+
+ +
+
+
//             ],
+
+
+
+ 55 +
+
+ +
+
+
//         ))),
+
+
+
+ 56 +
+
+ +
+
+
//         _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 57 +
+
+ +
+
+
//     }
+
+
+
+ 58 +
+
+ +
+
+
// }
+
+
+
+ 59 +
+
+ +
+
+

+            
+
+
+ 60 +
+
+ +
+
+
/**
+
+
+
+ 61 +
+
+ +
+
+
 * Convert a Geq to a SumGeq if the left hand side is a sum:
+
+
+
+ 62 +
+
+ +
+
+
 * ```text
+
+
+
+ 63 +
+
+ 1 +
+
+
 * sum([a, b, c]) >= d => sum_geq([a, b, c], d)
+
+
+
+ 64 +
+
+ 1 +
+
+
 * ```
+
+
+
+ 65 +
+
+ 1 +
+
+
 */
+
+
+
+ 66 +
+
+ +
+
+
#[register_rule(("Minion", 100))]
+
+
+
+ 67 +
+
+ 29625 +
+
+
fn flatten_sum_geq(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 68 +
+
+ 29625 +
+
+
    match expr {
+
+
+
+ 69 +
+
+ 360 +
+
+
        Expr::Geq(metadata, a, b) => {
+
+
+
+ 70 +
+
+ 360 +
+
+
            let exprs = sum_to_vector(a)?;
+
+
+
+ 71 +
+
+ 15 +
+
+
            Ok(Reduction::pure(Expr::SumGeq(
+
+
+
+ 72 +
+
+ 15 +
+
+
                metadata.clone(),
+
+
+
+ 73 +
+
+ 15 +
+
+
                exprs,
+
+
+
+ 74 +
+
+ 15 +
+
+
                b.clone(),
+
+
+
+ 75 +
+
+ 15 +
+
+
            )))
+
+
+
+ 76 +
+
+ +
+
+
        }
+
+
+
+ 77 +
+
+ 29265 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 78 +
+
+ +
+
+
    }
+
+
+
+ 79 +
+
+ 29625 +
+
+
}
+
+
+
+ 80 +
+
+ +
+
+

+            
+
+
+ 81 +
+
+ +
+
+
/**
+
+
+
+ 82 +
+
+ +
+
+
 * Convert a Leq to a SumLeq if the left hand side is a sum:
+
+
+
+ 83 +
+
+ +
+
+
 * ```text
+
+
+
+ 84 +
+
+ 1 +
+
+
 * sum([a, b, c]) <= d => sum_leq([a, b, c], d)
+
+
+
+ 85 +
+
+ 1 +
+
+
 * ```
+
+
+
+ 86 +
+
+ 1 +
+
+
 */
+
+
+
+ 87 +
+
+ +
+
+
#[register_rule(("Minion", 100))]
+
+
+
+ 88 +
+
+ 29625 +
+
+
fn sum_leq_to_sumleq(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 89 +
+
+ 29625 +
+
+
    match expr {
+
+
+
+ 90 +
+
+ 510 +
+
+
        Expr::Leq(metadata, a, b) => {
+
+
+
+ 91 +
+
+ 510 +
+
+
            let exprs = sum_to_vector(a)?;
+
+
+
+ 92 +
+
+ 15 +
+
+
            Ok(Reduction::pure(Expr::SumLeq(
+
+
+
+ 93 +
+
+ 15 +
+
+
                metadata.clone(),
+
+
+
+ 94 +
+
+ 15 +
+
+
                exprs,
+
+
+
+ 95 +
+
+ 15 +
+
+
                b.clone(),
+
+
+
+ 96 +
+
+ 15 +
+
+
            )))
+
+
+
+ 97 +
+
+ +
+
+
        }
+
+
+
+ 98 +
+
+ 29115 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 99 +
+
+ +
+
+
    }
+
+
+
+ 100 +
+
+ 29625 +
+
+
}
+
+
+
+ 101 +
+
+ +
+
+

+            
+
+
+ 102 +
+
+ +
+
+
/**
+
+
+
+ 103 +
+
+ +
+
+
 * Convert a 'Eq(Sum([...]))' to a SumEq
+
+
+
+ 104 +
+
+ +
+
+
 * ```text
+
+
+
+ 105 +
+
+ 1 +
+
+
 * eq(sum([a, b]), c) => sumeq([a, b], c)
+
+
+
+ 106 +
+
+ 1 +
+
+
 * ```
+
+
+
+ 107 +
+
+ 1 +
+
+
*/
+
+
+
+ 108 +
+
+ +
+
+
#[register_rule(("Minion", 100))]
+
+
+
+ 109 +
+
+ 29610 +
+
+
fn sum_eq_to_sumeq(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 110 +
+
+ 29610 +
+
+
    match expr {
+
+
+
+ 111 +
+
+ 45 +
+
+
        Expr::Eq(metadata, a, b) => {
+
+
+
+ 112 +
+
+ 45 +
+
+
            let exprs = sum_to_vector(a)?;
+
+
+
+ 113 +
+
+ 30 +
+
+
            Ok(Reduction::pure(Expr::SumEq(
+
+
+
+ 114 +
+
+ 30 +
+
+
                metadata.clone(),
+
+
+
+ 115 +
+
+ 30 +
+
+
                exprs,
+
+
+
+ 116 +
+
+ 30 +
+
+
                b.clone(),
+
+
+
+ 117 +
+
+ 30 +
+
+
            )))
+
+
+
+ 118 +
+
+ +
+
+
        }
+
+
+
+ 119 +
+
+ 29565 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 120 +
+
+ +
+
+
    }
+
+
+
+ 121 +
+
+ 29610 +
+
+
}
+
+
+
+ 122 +
+
+ +
+
+

+            
+
+
+ 123 +
+
+ +
+
+
/**
+
+
+
+ 124 +
+
+ +
+
+
 * Convert a `SumEq` to an `And(SumGeq, SumLeq)`
+
+
+
+ 125 +
+
+ +
+
+
 * This is a workaround for Minion not having support for a flat "equals" operation on sums
+
+
+
+ 126 +
+
+ +
+
+
 * ```text
+
+
+
+ 127 +
+
+ +
+
+
 * sumeq([a, b], c) -> watched_and({
+
+
+
+ 128 +
+
+ +
+
+
 *   sumleq([a, b], c),
+
+
+
+ 129 +
+
+ +
+
+
 *   sumgeq([a, b], c)
+
+
+
+ 130 +
+
+ 1 +
+
+
 * })
+
+
+
+ 131 +
+
+ 1 +
+
+
 * ```
+
+
+
+ 132 +
+
+ 1 +
+
+
 * I. e.
+
+
+
+ 133 +
+
+ +
+
+
 * ```text
+
+
+
+ 134 +
+
+ +
+
+
 * ((a + b) >= c) && ((a + b) <= c)
+
+
+
+ 135 +
+
+ 1 +
+
+
 * a + b = c
+
+
+
+ 136 +
+
+ 1 +
+
+
 * ```
+
+
+
+ 137 +
+
+ 1 +
+
+
 */
+
+
+
+ 138 +
+
+ +
+
+
#[register_rule(("Minion", 100))]
+
+
+
+ 139 +
+
+ 29610 +
+
+
fn sumeq_to_minion(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 140 +
+
+ 29610 +
+
+
    match expr {
+
+
+
+ 141 +
+
+ 30 +
+
+
        Expr::SumEq(metadata, exprs, eq_to) => Ok(Reduction::pure(Expr::And(
+
+
+
+ 142 +
+
+ 30 +
+
+
            metadata.clone(),
+
+
+
+ 143 +
+
+ 30 +
+
+
            vec![
+
+
+
+ 144 +
+
+ 30 +
+
+
                Expr::SumGeq(metadata.clone(), exprs.clone(), Box::from(*eq_to.clone())),
+
+
+
+ 145 +
+
+ 30 +
+
+
                Expr::SumLeq(metadata.clone(), exprs.clone(), Box::from(*eq_to.clone())),
+
+
+
+ 146 +
+
+ 30 +
+
+
            ],
+
+
+
+ 147 +
+
+ 30 +
+
+
        ))),
+
+
+
+ 148 +
+
+ 29580 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 149 +
+
+ +
+
+
    }
+
+
+
+ 150 +
+
+ 29610 +
+
+
}
+
+
+
+ 151 +
+
+ +
+
+

+            
+
+
+ 152 +
+
+ +
+
+
/**
+
+
+
+ 153 +
+
+ +
+
+
* Convert a Lt to an Ineq:
+
+
+
+ 154 +
+
+ +
+
+

+            
+
+
+ 155 +
+
+ +
+
+
* ```text
+
+
+
+ 156 +
+
+ 1 +
+
+
* a < b => a - b < -1
+
+
+
+ 157 +
+
+ 1 +
+
+
* ```
+
+
+
+ 158 +
+
+ 1 +
+
+
*/
+
+
+
+ 159 +
+
+ +
+
+
#[register_rule(("Minion", 100))]
+
+
+
+ 160 +
+
+ 29625 +
+
+
fn lt_to_ineq(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 161 +
+
+ 29625 +
+
+
    match expr {
+
+
+
+ 162 +
+
+ 30 +
+
+
        Expr::Lt(metadata, a, b) => Ok(Reduction::pure(Expr::Ineq(
+
+
+
+ 163 +
+
+ 30 +
+
+
            metadata.clone(),
+
+
+
+ 164 +
+
+ 30 +
+
+
            a.clone(),
+
+
+
+ 165 +
+
+ 30 +
+
+
            b.clone(),
+
+
+
+ 166 +
+
+ 30 +
+
+
            Box::new(Expr::Constant(Metadata::new(), Const::Int(-1))),
+
+
+
+ 167 +
+
+ 30 +
+
+
        ))),
+
+
+
+ 168 +
+
+ 29595 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 169 +
+
+ +
+
+
    }
+
+
+
+ 170 +
+
+ 29625 +
+
+
}
+
+
+
+ 171 +
+
+ +
+
+

+            
+
+
+ 172 +
+
+ +
+
+
/**
+
+
+
+ 173 +
+
+ +
+
+
* Convert a Gt to an Ineq:
+
+
+
+ 174 +
+
+ +
+
+
*
+
+
+
+ 175 +
+
+ +
+
+
* ```text
+
+
+
+ 176 +
+
+ 1 +
+
+
* a > b => b - a < -1
+
+
+
+ 177 +
+
+ 1 +
+
+
* ```
+
+
+
+ 178 +
+
+ 1 +
+
+
*/
+
+
+
+ 179 +
+
+ +
+
+
#[register_rule(("Minion", 100))]
+
+
+
+ 180 +
+
+ 29610 +
+
+
fn gt_to_ineq(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 181 +
+
+ 29610 +
+
+
    match expr {
+
+
+
+ 182 +
+
+ +
+
+
        Expr::Gt(metadata, a, b) => Ok(Reduction::pure(Expr::Ineq(
+
+
+
+ 183 +
+
+ +
+
+
            metadata.clone(),
+
+
+
+ 184 +
+
+ +
+
+
            b.clone(),
+
+
+
+ 185 +
+
+ +
+
+
            a.clone(),
+
+
+
+ 186 +
+
+ +
+
+
            Box::new(Expr::Constant(Metadata::new(), Const::Int(-1))),
+
+
+
+ 187 +
+
+ +
+
+
        ))),
+
+
+
+ 188 +
+
+ 29610 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 189 +
+
+ +
+
+
    }
+
+
+
+ 190 +
+
+ 29610 +
+
+
}
+
+
+
+ 191 +
+
+ +
+
+

+            
+
+
+ 192 +
+
+ +
+
+
/**
+
+
+
+ 193 +
+
+ +
+
+
* Convert a Geq to an Ineq:
+
+
+
+ 194 +
+
+ +
+
+
*
+
+
+
+ 195 +
+
+ +
+
+
* ```text
+
+
+
+ 196 +
+
+ 1 +
+
+
* a >= b => b - a < 0
+
+
+
+ 197 +
+
+ 1 +
+
+
* ```
+
+
+
+ 198 +
+
+ 1 +
+
+
*/
+
+
+
+ 199 +
+
+ +
+
+
#[register_rule(("Minion", 100))]
+
+
+
+ 200 +
+
+ 29610 +
+
+
fn geq_to_ineq(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 201 +
+
+ 29610 +
+
+
    match expr {
+
+
+
+ 202 +
+
+ 345 +
+
+
        Expr::Geq(metadata, a, b) => Ok(Reduction::pure(Expr::Ineq(
+
+
+
+ 203 +
+
+ 345 +
+
+
            metadata.clone(),
+
+
+
+ 204 +
+
+ 345 +
+
+
            b.clone(),
+
+
+
+ 205 +
+
+ 345 +
+
+
            a.clone(),
+
+
+
+ 206 +
+
+ 345 +
+
+
            Box::new(Expr::Constant(Metadata::new(), Const::Int(0))),
+
+
+
+ 207 +
+
+ 345 +
+
+
        ))),
+
+
+
+ 208 +
+
+ 29265 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 209 +
+
+ +
+
+
    }
+
+
+
+ 210 +
+
+ 29610 +
+
+
}
+
+
+
+ 211 +
+
+ +
+
+

+            
+
+
+ 212 +
+
+ +
+
+
/**
+
+
+
+ 213 +
+
+ +
+
+
* Convert a Leq to an Ineq:
+
+
+
+ 214 +
+
+ +
+
+
*
+
+
+
+ 215 +
+
+ +
+
+
* ```text
+
+
+
+ 216 +
+
+ 1 +
+
+
* a <= b => a - b < 0
+
+
+
+ 217 +
+
+ 1 +
+
+
* ```
+
+
+
+ 218 +
+
+ 1 +
+
+
*/
+
+
+
+ 219 +
+
+ +
+
+
#[register_rule(("Minion", 100))]
+
+
+
+ 220 +
+
+ 29610 +
+
+
fn leq_to_ineq(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 221 +
+
+ 29610 +
+
+
    match expr {
+
+
+
+ 222 +
+
+ 495 +
+
+
        Expr::Leq(metadata, a, b) => Ok(Reduction::pure(Expr::Ineq(
+
+
+
+ 223 +
+
+ 495 +
+
+
            metadata.clone(),
+
+
+
+ 224 +
+
+ 495 +
+
+
            a.clone(),
+
+
+
+ 225 +
+
+ 495 +
+
+
            b.clone(),
+
+
+
+ 226 +
+
+ 495 +
+
+
            Box::new(Expr::Constant(Metadata::new(), Const::Int(0))),
+
+
+
+ 227 +
+
+ 495 +
+
+
        ))),
+
+
+
+ 228 +
+
+ 29115 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 229 +
+
+ +
+
+
    }
+
+
+
+ 230 +
+
+ 29610 +
+
+
}
+
+
+
+ 231 +
+
+ +
+
+

+            
+
+
+ 232 +
+
+ +
+
+
// #[register_rule(("Minion", 100))]
+
+
+
+ 233 +
+
+ +
+
+
// fn safediv_eq_to_diveq(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 234 +
+
+ +
+
+
//     match expr {
+
+
+
+ 235 +
+
+ +
+
+
//         Expr::Eq(metadata, a, b) => {
+
+
+
+ 236 +
+
+ +
+
+
//             if let Expr::SafeDiv(_, x, y) = a.as_ref() {
+
+
+
+ 237 +
+
+ +
+
+
//                 if !(b.is_reference() || b.is_constant()) {
+
+
+
+ 238 +
+
+ +
+
+
//                     return Err(ApplicationError::RuleNotApplicable);
+
+
+
+ 239 +
+
+ +
+
+
//                 }
+
+
+
+ 240 +
+
+ +
+
+
//                 Ok(Reduction::pure(Expr::DivEq(
+
+
+
+ 241 +
+
+ +
+
+
//                     metadata.clone(),
+
+
+
+ 242 +
+
+ +
+
+
//                     x.clone(),
+
+
+
+ 243 +
+
+ +
+
+
//                     y.clone(),
+
+
+
+ 244 +
+
+ +
+
+
//                     b.clone(),
+
+
+
+ 245 +
+
+ +
+
+
//                 )))
+
+
+
+ 246 +
+
+ +
+
+
//             } else if let Expr::SafeDiv(_, x, y) = b.as_ref() {
+
+
+
+ 247 +
+
+ +
+
+
//                 if !(a.is_reference() || a.is_constant()) {
+
+
+
+ 248 +
+
+ +
+
+
//                     return Err(ApplicationError::RuleNotApplicable);
+
+
+
+ 249 +
+
+ +
+
+
//                 }
+
+
+
+ 250 +
+
+ +
+
+
//                 Ok(Reduction::pure(Expr::DivEq(
+
+
+
+ 251 +
+
+ +
+
+
//                     metadata.clone(),
+
+
+
+ 252 +
+
+ +
+
+
//                     x.clone(),
+
+
+
+ 253 +
+
+ +
+
+
//                     y.clone(),
+
+
+
+ 254 +
+
+ +
+
+
//                     a.clone(),
+
+
+
+ 255 +
+
+ +
+
+
//                 )))
+
+
+
+ 256 +
+
+ +
+
+
//             } else {
+
+
+
+ 257 +
+
+ +
+
+
//                 Err(ApplicationError::RuleNotApplicable)
+
+
+
+ 258 +
+
+ +
+
+
//             }
+
+
+
+ 259 +
+
+ +
+
+
//         }
+
+
+
+ 260 +
+
+ +
+
+
//         _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 261 +
+
+ +
+
+
//     }
+
+
+
+ 262 +
+
+ +
+
+
// }
+
+
+
+ 263 +
+
+ +
+
+

+            
+
+
+ 264 +
+
+ +
+
+
#[register_rule(("Minion", 100))]
+
+
+
+ 265 +
+
+ 29610 +
+
+
fn neq_to_alldiff(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 266 +
+
+ 29610 +
+
+
    match expr {
+
+
+
+ 267 +
+
+ 30 +
+
+
        Expr::Neq(metadata, a, b) => Ok(Reduction::pure(Expr::AllDiff(
+
+
+
+ 268 +
+
+ 30 +
+
+
            metadata.clone(),
+
+
+
+ 269 +
+
+ 30 +
+
+
            vec![*a.clone(), *b.clone()],
+
+
+
+ 270 +
+
+ 30 +
+
+
        ))),
+
+
+
+ 271 +
+
+ 29580 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 272 +
+
+ +
+
+
    }
+
+
+
+ 273 +
+
+ 29610 +
+
+
}
+
+
+
+ 274 +
+
+ +
+
+

+            
+
+
+ 275 +
+
+ +
+
+
#[register_rule(("Minion", 99))]
+
+
+
+ 276 +
+
+ 29610 +
+
+
fn eq_to_leq_geq(expr: &Expr, _: &Model) -> ApplicationResult {
+
+
+
+ 277 +
+
+ 29610 +
+
+
    match expr {
+
+
+
+ 278 +
+
+ 45 +
+
+
        Expr::Eq(metadata, a, b) => {
+
+
+
+ 279 +
+
+ 45 +
+
+
            if let Ok(exprs) = sum_to_vector(a) {
+
+
+
+ 280 +
+
+ 30 +
+
+
                Ok(Reduction::pure(Expr::SumEq(
+
+
+
+ 281 +
+
+ 30 +
+
+
                    metadata.clone(),
+
+
+
+ 282 +
+
+ 30 +
+
+
                    exprs,
+
+
+
+ 283 +
+
+ 30 +
+
+
                    b.clone(),
+
+
+
+ 284 +
+
+ 30 +
+
+
                )))
+
+
+
+ 285 +
+
+ 15 +
+
+
            } else if let Ok(exprs) = sum_to_vector(b) {
+
+
+
+ 286 +
+
+ +
+
+
                Ok(Reduction::pure(Expr::SumEq(
+
+
+
+ 287 +
+
+ +
+
+
                    metadata.clone(),
+
+
+
+ 288 +
+
+ +
+
+
                    exprs,
+
+
+
+ 289 +
+
+ +
+
+
                    a.clone(),
+
+
+
+ 290 +
+
+ +
+
+
                )))
+
+
+
+ 291 +
+
+ +
+
+
            } else {
+
+
+
+ 292 +
+
+ 15 +
+
+
                Err(ApplicationError::RuleNotApplicable)
+
+
+
+ 293 +
+
+ +
+
+
            }
+
+
+
+ 294 +
+
+ +
+
+
        }
+
+
+
+ 295 +
+
+ 29565 +
+
+
        _ => Err(ApplicationError::RuleNotApplicable),
+
+
+
+ 296 +
+
+ +
+
+
    }
+
+
+
+ 297 +
+
+ 29610 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/adaptors/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/adaptors/index.html new file mode 100644 index 0000000000..ff75f74bd8 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/adaptors/index.html @@ -0,0 +1,122 @@ + + + + + Grcov report - crates/conjure_core/src/solver/adaptors + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
kissat.rs + + 0% + + + 0% + + 0 / 30 + 0%0 / 18
minion.rs + + 85.12% + + + 85.12% + + 206 / 242 + 25.93%21 / 81
sat_common.rs + + 0% + + + 0% + + 0 / 158 + 0%0 / 66
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/adaptors/kissat.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/adaptors/kissat.rs.html new file mode 100644 index 0000000000..1aba29c037 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/adaptors/kissat.rs.html @@ -0,0 +1,1049 @@ + + + + + Grcov report - kissat.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use crate::solver::{SolveSuccess, SolverCallback, SolverFamily, SolverMutCallback};
+
+
+
+ 2 +
+
+ +
+
+
use crate::Model as ConjureModel;
+
+
+
+ 3 +
+
+ +
+
+

+            
+
+
+ 4 +
+
+ +
+
+
use super::super::model_modifier::NotModifiable;
+
+
+
+ 5 +
+
+ +
+
+
use super::super::private;
+
+
+
+ 6 +
+
+ +
+
+
use super::super::SearchComplete::*;
+
+
+
+ 7 +
+
+ +
+
+
use super::super::SearchIncomplete::*;
+
+
+
+ 8 +
+
+ +
+
+
use super::super::SearchStatus::*;
+
+
+
+ 9 +
+
+ +
+
+
use super::super::SolverAdaptor;
+
+
+
+ 10 +
+
+ +
+
+
use super::super::SolverError;
+
+
+
+ 11 +
+
+ +
+
+
use super::super::SolverError::*;
+
+
+
+ 12 +
+
+ +
+
+
use super::super::SolverError::*;
+
+
+
+ 13 +
+
+ +
+
+
use super::sat_common::CNFModel;
+
+
+
+ 14 +
+
+ +
+
+

+            
+
+
+ 15 +
+
+ +
+
+
/// A [SolverAdaptor] for interacting with the Kissat SAT solver.
+
+
+
+ 16 +
+
+ +
+
+
pub struct Kissat {
+
+
+
+ 17 +
+
+ +
+
+
    __non_constructable: private::Internal,
+
+
+
+ 18 +
+
+ +
+
+
    model: Option<CNFModel>,
+
+
+
+ 19 +
+
+ +
+
+
}
+
+
+
+ 20 +
+
+ +
+
+

+            
+
+
+ 21 +
+
+ +
+
+
impl private::Sealed for Kissat {}
+
+
+
+ 22 +
+
+ +
+
+

+            
+
+
+ 23 +
+
+ +
+
+
impl Kissat {
+
+
+
+ 24 +
+
+ +
+
+
    pub fn new() -> Self {
+
+
+
+ 25 +
+
+ +
+
+
        Kissat {
+
+
+
+ 26 +
+
+ +
+
+
            __non_constructable: private::Internal,
+
+
+
+ 27 +
+
+ +
+
+
            model: None,
+
+
+
+ 28 +
+
+ +
+
+
        }
+
+
+
+ 29 +
+
+ +
+
+
    }
+
+
+
+ 30 +
+
+ +
+
+
}
+
+
+
+ 31 +
+
+ +
+
+

+            
+
+
+ 32 +
+
+ +
+
+
impl Default for Kissat {
+
+
+
+ 33 +
+
+ +
+
+
    fn default() -> Self {
+
+
+
+ 34 +
+
+ +
+
+
        Kissat::new()
+
+
+
+ 35 +
+
+ +
+
+
    }
+
+
+
+ 36 +
+
+ +
+
+
}
+
+
+
+ 37 +
+
+ +
+
+

+            
+
+
+ 38 +
+
+ +
+
+
impl SolverAdaptor for Kissat {
+
+
+
+ 39 +
+
+ +
+
+
    fn solve(
+
+
+
+ 40 +
+
+ +
+
+
        &mut self,
+
+
+
+ 41 +
+
+ +
+
+
        callback: SolverCallback,
+
+
+
+ 42 +
+
+ +
+
+
        _: private::Internal,
+
+
+
+ 43 +
+
+ +
+
+
    ) -> Result<SolveSuccess, SolverError> {
+
+
+
+ 44 +
+
+ +
+
+
        Err(OpNotImplemented("solve(): todo!".to_owned()))
+
+
+
+ 45 +
+
+ +
+
+
    }
+
+
+
+ 46 +
+
+ +
+
+

+            
+
+
+ 47 +
+
+ +
+
+
    fn solve_mut(
+
+
+
+ 48 +
+
+ +
+
+
        &mut self,
+
+
+
+ 49 +
+
+ +
+
+
        callback: SolverMutCallback,
+
+
+
+ 50 +
+
+ +
+
+
        _: private::Internal,
+
+
+
+ 51 +
+
+ +
+
+
    ) -> Result<SolveSuccess, SolverError> {
+
+
+
+ 52 +
+
+ +
+
+
        Err(OpNotSupported("solve_mut".to_owned()))
+
+
+
+ 53 +
+
+ +
+
+
    }
+
+
+
+ 54 +
+
+ +
+
+

+            
+
+
+ 55 +
+
+ +
+
+
    fn load_model(&mut self, model: ConjureModel, _: private::Internal) -> Result<(), SolverError> {
+
+
+
+ 56 +
+
+ +
+
+
        self.model = Some(CNFModel::from_conjure(model)?);
+
+
+
+ 57 +
+
+ +
+
+
        Ok(())
+
+
+
+ 58 +
+
+ +
+
+
    }
+
+
+
+ 59 +
+
+ +
+
+

+            
+
+
+ 60 +
+
+ +
+
+
    fn get_family(&self) -> SolverFamily {
+
+
+
+ 61 +
+
+ +
+
+
        SolverFamily::SAT
+
+
+
+ 62 +
+
+ +
+
+
    }
+
+
+
+ 63 +
+
+ +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/adaptors/minion.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/adaptors/minion.rs.html new file mode 100644 index 0000000000..5b51b6b8d2 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/adaptors/minion.rs.html @@ -0,0 +1,5625 @@ + + + + + Grcov report - minion.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use std::collections::HashMap;
+
+
+
+ 2 +
+
+ +
+
+
use std::sync::{Mutex, OnceLock};
+
+
+
+ 3 +
+
+ +
+
+

+            
+
+
+ 4 +
+
+ +
+
+
use regex::Regex;
+
+
+
+ 5 +
+
+ +
+
+

+            
+
+
+ 6 +
+
+ +
+
+
use minion_ast::Model as MinionModel;
+
+
+
+ 7 +
+
+ +
+
+
use minion_rs::ast as minion_ast;
+
+
+
+ 8 +
+
+ +
+
+
use minion_rs::error::MinionError;
+
+
+
+ 9 +
+
+ +
+
+
use minion_rs::run_minion;
+
+
+
+ 10 +
+
+ +
+
+

+            
+
+
+ 11 +
+
+ +
+
+
use crate::ast as conjure_ast;
+
+
+
+ 12 +
+
+ +
+
+
use crate::solver::SolverCallback;
+
+
+
+ 13 +
+
+ +
+
+
use crate::solver::SolverFamily;
+
+
+
+ 14 +
+
+ +
+
+
use crate::solver::SolverMutCallback;
+
+
+
+ 15 +
+
+ +
+
+
use crate::Model as ConjureModel;
+
+
+
+ 16 +
+
+ +
+
+

+            
+
+
+ 17 +
+
+ +
+
+
use super::super::model_modifier::NotModifiable;
+
+
+
+ 18 +
+
+ +
+
+
use super::super::private;
+
+
+
+ 19 +
+
+ +
+
+
use super::super::SearchComplete::*;
+
+
+
+ 20 +
+
+ +
+
+
use super::super::SearchIncomplete::*;
+
+
+
+ 21 +
+
+ +
+
+
use super::super::SearchStatus::*;
+
+
+
+ 22 +
+
+ +
+
+
use super::super::SolveSuccess;
+
+
+
+ 23 +
+
+ +
+
+
use super::super::SolverAdaptor;
+
+
+
+ 24 +
+
+ +
+
+
use super::super::SolverError;
+
+
+
+ 25 +
+
+ +
+
+
use super::super::SolverError::*;
+
+
+
+ 26 +
+
+ +
+
+

+            
+
+
+ 27 +
+
+ +
+
+
/// A [SolverAdaptor] for interacting with Minion.
+
+
+
+ 28 +
+
+ +
+
+
///
+
+
+
+ 29 +
+
+ +
+
+
/// This adaptor uses the `minion_rs` crate to talk to Minion over FFI.
+
+
+
+ 30 +
+
+ +
+
+
pub struct Minion {
+
+
+
+ 31 +
+
+ +
+
+
    __non_constructable: private::Internal,
+
+
+
+ 32 +
+
+ +
+
+
    model: Option<MinionModel>,
+
+
+
+ 33 +
+
+ +
+
+
}
+
+
+
+ 34 +
+
+ +
+
+

+            
+
+
+ 35 +
+
+ +
+
+
static MINION_LOCK: Mutex<()> = Mutex::new(());
+
+
+
+ 36 +
+
+ +
+
+
static USER_CALLBACK: OnceLock<Mutex<SolverCallback>> = OnceLock::new();
+
+
+
+ 37 +
+
+ +
+
+
static ANY_SOLUTIONS: Mutex<bool> = Mutex::new(false);
+
+
+
+ 38 +
+
+ +
+
+
static USER_TERMINATED: Mutex<bool> = Mutex::new(false);
+
+
+
+ 39 +
+
+ +
+
+

+            
+
+
+ 40 +
+
+ +
+
+
#[allow(clippy::unwrap_used)]
+
+
+
+ 41 +
+
+ 585 +
+
+
fn minion_rs_callback(solutions: HashMap<minion_ast::VarName, minion_ast::Constant>) -> bool {
+
+
+
+ 42 +
+
+ 585 +
+
+
    *(ANY_SOLUTIONS.lock().unwrap()) = true;
+
+
+
+ 43 +
+
+ 585 +
+
+
    let callback = USER_CALLBACK
+
+
+
+ 44 +
+
+ 585 +
+
+
        .get_or_init(|| Mutex::new(Box::new(|x| true)))
+
+
+
+ 45 +
+
+ 585 +
+
+
        .lock()
+
+
+
+ 46 +
+
+ 585 +
+
+
        .unwrap();
+
+
+
+ 47 +
+
+ 585 +
+
+

+            
+
+
+ 48 +
+
+ 585 +
+
+
    let mut conjure_solutions: HashMap<conjure_ast::Name, conjure_ast::Constant> = HashMap::new();
+
+
+
+ 49 +
+
+ 1575 +
+
+
    for (minion_name, minion_const) in solutions.into_iter() {
+
+
+
+ 50 +
+
+ 1575 +
+
+
        let conjure_const = match minion_const {
+
+
+
+ 51 +
+
+ +
+
+
            minion_ast::Constant::Bool(x) => conjure_ast::Constant::Bool(x),
+
+
+
+ 52 +
+
+ 1575 +
+
+
            minion_ast::Constant::Integer(x) => conjure_ast::Constant::Int(x),
+
+
+
+ 53 +
+
+ +
+
+
            _ => todo!(),
+
+
+
+ 54 +
+
+ +
+
+
        };
+
+
+
+ 55 +
+
+ +
+
+

+            
+
+
+ 56 +
+
+ 1575 +
+
+
        let machine_name_re = Regex::new(r"__conjure_machine_name_([0-9]+)").unwrap();
+
+
+
+ 57 +
+
+ 1575 +
+
+
        let conjure_name = if let Some(caps) = machine_name_re.captures(&minion_name) {
+
+
+
+ 58 +
+
+ 375 +
+
+
            conjure_ast::Name::MachineName(caps[1].parse::<i32>().unwrap())
+
+
+
+ 59 +
+
+ +
+
+
        } else {
+
+
+
+ 60 +
+
+ 1200 +
+
+
            conjure_ast::Name::UserName(minion_name)
+
+
+
+ 61 +
+
+ +
+
+
        };
+
+
+
+ 62 +
+
+ +
+
+

+            
+
+
+ 63 +
+
+ 1575 +
+
+
        conjure_solutions.insert(conjure_name, conjure_const);
+
+
+
+ 64 +
+
+ +
+
+
    }
+
+
+
+ 65 +
+
+ +
+
+

+            
+
+
+ 66 +
+
+ 585 +
+
+
    let continue_search = (**callback)(conjure_solutions);
+
+
+
+ 67 +
+
+ 585 +
+
+
    if !continue_search {
+
+
+
+ 68 +
+
+ +
+
+
        *(USER_TERMINATED.lock().unwrap()) = true;
+
+
+
+ 69 +
+
+ 585 +
+
+
    }
+
+
+
+ 70 +
+
+ +
+
+

+            
+
+
+ 71 +
+
+ 585 +
+
+
    continue_search
+
+
+
+ 72 +
+
+ 585 +
+
+
}
+
+
+
+ 73 +
+
+ +
+
+

+            
+
+
+ 74 +
+
+ +
+
+
impl private::Sealed for Minion {}
+
+
+
+ 75 +
+
+ +
+
+

+            
+
+
+ 76 +
+
+ +
+
+
impl Minion {
+
+
+
+ 77 +
+
+ 180 +
+
+
    pub fn new() -> Minion {
+
+
+
+ 78 +
+
+ 180 +
+
+
        Minion {
+
+
+
+ 79 +
+
+ 180 +
+
+
            __non_constructable: private::Internal,
+
+
+
+ 80 +
+
+ 180 +
+
+
            model: None,
+
+
+
+ 81 +
+
+ 180 +
+
+
        }
+
+
+
+ 82 +
+
+ 180 +
+
+
    }
+
+
+
+ 83 +
+
+ +
+
+
}
+
+
+
+ 84 +
+
+ +
+
+

+            
+
+
+ 85 +
+
+ +
+
+
impl Default for Minion {
+
+
+
+ 86 +
+
+ +
+
+
    fn default() -> Self {
+
+
+
+ 87 +
+
+ +
+
+
        Minion::new()
+
+
+
+ 88 +
+
+ +
+
+
    }
+
+
+
+ 89 +
+
+ +
+
+
}
+
+
+
+ 90 +
+
+ +
+
+

+            
+
+
+ 91 +
+
+ +
+
+
impl SolverAdaptor for Minion {
+
+
+
+ 92 +
+
+ +
+
+
    #[allow(clippy::unwrap_used)]
+
+
+
+ 93 +
+
+ 180 +
+
+
    fn solve(
+
+
+
+ 94 +
+
+ 180 +
+
+
        &mut self,
+
+
+
+ 95 +
+
+ 180 +
+
+
        callback: SolverCallback,
+
+
+
+ 96 +
+
+ 180 +
+
+
        _: private::Internal,
+
+
+
+ 97 +
+
+ 180 +
+
+
    ) -> Result<SolveSuccess, SolverError> {
+
+
+
+ 98 +
+
+ 180 +
+
+
        // our minion callback is global state, so single threading the adaptor as a whole is
+
+
+
+ 99 +
+
+ 180 +
+
+
        // probably a good move...
+
+
+
+ 100 +
+
+ 180 +
+
+
        #[allow(clippy::unwrap_used)]
+
+
+
+ 101 +
+
+ 180 +
+
+
        let mut minion_lock = MINION_LOCK.lock().unwrap();
+
+
+
+ 102 +
+
+ 180 +
+
+

+            
+
+
+ 103 +
+
+ 180 +
+
+
        #[allow(clippy::unwrap_used)]
+
+
+
+ 104 +
+
+ 180 +
+
+
        let mut user_callback = USER_CALLBACK
+
+
+
+ 105 +
+
+ 180 +
+
+
            .get_or_init(|| Mutex::new(Box::new(|x| true)))
+
+
+
+ 106 +
+
+ 180 +
+
+
            .lock()
+
+
+
+ 107 +
+
+ 180 +
+
+
            .unwrap();
+
+
+
+ 108 +
+
+ 180 +
+
+
        *user_callback = callback;
+
+
+
+ 109 +
+
+ 180 +
+
+
        drop(user_callback); // release mutex. REQUIRED so that run_minion can use the
+
+
+
+ 110 +
+
+ 180 +
+
+
                             // user callback and not deadlock.
+
+
+
+ 111 +
+
+ 180 +
+
+

+            
+
+
+ 112 +
+
+ 180 +
+
+
        run_minion(
+
+
+
+ 113 +
+
+ 180 +
+
+
            self.model.clone().expect("STATE MACHINE ERR"),
+
+
+
+ 114 +
+
+ 180 +
+
+
            minion_rs_callback,
+
+
+
+ 115 +
+
+ 180 +
+
+
        )
+
+
+
+ 116 +
+
+ 180 +
+
+
        .map_err(|err| match err {
+
+
+
+ 117 +
+
+ +
+
+
            MinionError::RuntimeError(x) => Runtime(format!("{:#?}", x)),
+
+
+
+ 118 +
+
+ +
+
+
            MinionError::Other(x) => Runtime(format!("{:#?}", x)),
+
+
+
+ 119 +
+
+ +
+
+
            MinionError::NotImplemented(x) => RuntimeNotImplemented(x),
+
+
+
+ 120 +
+
+ +
+
+
            x => Runtime(format!("unknown minion_rs error: {:#?}", x)),
+
+
+
+ 121 +
+
+ 180 +
+
+
        })?;
+
+
+
+ 122 +
+
+ +
+
+

+            
+
+
+ 123 +
+
+ 180 +
+
+
        let mut status = Complete(HasSolutions);
+
+
+
+ 124 +
+
+ 180 +
+
+
        if *(USER_TERMINATED.lock()).unwrap() {
+
+
+
+ 125 +
+
+ +
+
+
            status = Incomplete(UserTerminated);
+
+
+
+ 126 +
+
+ 180 +
+
+
        } else if *(ANY_SOLUTIONS.lock()).unwrap() {
+
+
+
+ 127 +
+
+ 180 +
+
+
            status = Complete(NoSolutions);
+
+
+
+ 128 +
+
+ 180 +
+
+
        }
+
+
+
+ 129 +
+
+ 180 +
+
+
        Ok(SolveSuccess {
+
+
+
+ 130 +
+
+ 180 +
+
+
            stats: Default::default(),
+
+
+
+ 131 +
+
+ 180 +
+
+
            status,
+
+
+
+ 132 +
+
+ 180 +
+
+
        })
+
+
+
+ 133 +
+
+ 180 +
+
+
    }
+
+
+
+ 134 +
+
+ +
+
+

+            
+
+
+ 135 +
+
+ +
+
+
    fn solve_mut(
+
+
+
+ 136 +
+
+ +
+
+
        &mut self,
+
+
+
+ 137 +
+
+ +
+
+
        callback: SolverMutCallback,
+
+
+
+ 138 +
+
+ +
+
+
        _: private::Internal,
+
+
+
+ 139 +
+
+ +
+
+
    ) -> Result<SolveSuccess, SolverError> {
+
+
+
+ 140 +
+
+ +
+
+
        Err(OpNotImplemented("solve_mut".into()))
+
+
+
+ 141 +
+
+ +
+
+
    }
+
+
+
+ 142 +
+
+ +
+
+

+            
+
+
+ 143 +
+
+ 180 +
+
+
    fn load_model(&mut self, model: ConjureModel, _: private::Internal) -> Result<(), SolverError> {
+
+
+
+ 144 +
+
+ 180 +
+
+
        let mut minion_model = MinionModel::new();
+
+
+
+ 145 +
+
+ 180 +
+
+
        parse_vars(&model, &mut minion_model)?;
+
+
+
+ 146 +
+
+ 180 +
+
+
        parse_exprs(&model, &mut minion_model)?;
+
+
+
+ 147 +
+
+ 180 +
+
+
        self.model = Some(minion_model);
+
+
+
+ 148 +
+
+ 180 +
+
+
        Ok(())
+
+
+
+ 149 +
+
+ 180 +
+
+
    }
+
+
+
+ 150 +
+
+ +
+
+

+            
+
+
+ 151 +
+
+ 180 +
+
+
    fn get_family(&self) -> SolverFamily {
+
+
+
+ 152 +
+
+ 180 +
+
+
        SolverFamily::Minion
+
+
+
+ 153 +
+
+ 180 +
+
+
    }
+
+
+
+ 154 +
+
+ +
+
+

+            
+
+
+ 155 +
+
+ 180 +
+
+
    fn get_name(&self) -> Option<String> {
+
+
+
+ 156 +
+
+ 180 +
+
+
        Some("adaptors::Minion".to_owned())
+
+
+
+ 157 +
+
+ 180 +
+
+
    }
+
+
+
+ 158 +
+
+ +
+
+
}
+
+
+
+ 159 +
+
+ +
+
+

+            
+
+
+ 160 +
+
+ 180 +
+
+
fn parse_vars(
+
+
+
+ 161 +
+
+ 180 +
+
+
    conjure_model: &ConjureModel,
+
+
+
+ 162 +
+
+ 180 +
+
+
    minion_model: &mut MinionModel,
+
+
+
+ 163 +
+
+ 180 +
+
+
) -> Result<(), SolverError> {
+
+
+
+ 164 +
+
+ +
+
+
    // TODO (niklasdewally): remove unused vars?
+
+
+
+ 165 +
+
+ +
+
+
    // TODO (niklasdewally): ensure all vars references are used.
+
+
+
+ 166 +
+
+ +
+
+

+            
+
+
+ 167 +
+
+ 465 +
+
+
    for (name, variable) in conjure_model.variables.iter() {
+
+
+
+ 168 +
+
+ 465 +
+
+
        parse_var(name, variable, minion_model)?;
+
+
+
+ 169 +
+
+ +
+
+
    }
+
+
+
+ 170 +
+
+ 180 +
+
+
    Ok(())
+
+
+
+ 171 +
+
+ 180 +
+
+
}
+
+
+
+ 172 +
+
+ +
+
+

+            
+
+
+ 173 +
+
+ 465 +
+
+
fn parse_var(
+
+
+
+ 174 +
+
+ 465 +
+
+
    name: &conjure_ast::Name,
+
+
+
+ 175 +
+
+ 465 +
+
+
    var: &conjure_ast::DecisionVariable,
+
+
+
+ 176 +
+
+ 465 +
+
+
    minion_model: &mut MinionModel,
+
+
+
+ 177 +
+
+ 465 +
+
+
) -> Result<(), SolverError> {
+
+
+
+ 178 +
+
+ 465 +
+
+
    match &var.domain {
+
+
+
+ 179 +
+
+ 360 +
+
+
        conjure_ast::Domain::IntDomain(ranges) => _parse_intdomain_var(name, ranges, minion_model),
+
+
+
+ 180 +
+
+ 105 +
+
+
        conjure_ast::Domain::BoolDomain => _parse_booldomain_var(name, minion_model),
+
+
+
+ 181 +
+
+ +
+
+
        x => Err(ModelFeatureNotSupported(format!("{:?}", x))),
+
+
+
+ 182 +
+
+ +
+
+
    }
+
+
+
+ 183 +
+
+ 465 +
+
+
}
+
+
+
+ 184 +
+
+ +
+
+

+            
+
+
+ 185 +
+
+ 360 +
+
+
fn _parse_intdomain_var(
+
+
+
+ 186 +
+
+ 360 +
+
+
    name: &conjure_ast::Name,
+
+
+
+ 187 +
+
+ 360 +
+
+
    ranges: &[conjure_ast::Range<i32>],
+
+
+
+ 188 +
+
+ 360 +
+
+
    minion_model: &mut MinionModel,
+
+
+
+ 189 +
+
+ 360 +
+
+
) -> Result<(), SolverError> {
+
+
+
+ 190 +
+
+ 360 +
+
+
    let str_name = _name_to_string(name.to_owned());
+
+
+
+ 191 +
+
+ 360 +
+
+

+            
+
+
+ 192 +
+
+ 360 +
+
+
    if ranges.len() != 1 {
+
+
+
+ 193 +
+
+ +
+
+
        return Err(ModelFeatureNotImplemented(format!(
+
+
+
+ 194 +
+
+ +
+
+
            "variable {:?} has {:?} ranges. Multiple ranges / SparseBound is not yet supported.",
+
+
+
+ 195 +
+
+ +
+
+
            str_name,
+
+
+
+ 196 +
+
+ +
+
+
            ranges.len()
+
+
+
+ 197 +
+
+ +
+
+
        )));
+
+
+
+ 198 +
+
+ 360 +
+
+
    }
+
+
+
+ 199 +
+
+ +
+
+

+            
+
+
+ 200 +
+
+ 360 +
+
+
    let range = ranges.first().ok_or(ModelInvalid(format!(
+
+
+
+ 201 +
+
+ 360 +
+
+
        "variable {:?} has no range",
+
+
+
+ 202 +
+
+ 360 +
+
+
        str_name
+
+
+
+ 203 +
+
+ 360 +
+
+
    )))?;
+
+
+
+ 204 +
+
+ +
+
+

+            
+
+
+ 205 +
+
+ 360 +
+
+
    let (low, high) = match range {
+
+
+
+ 206 +
+
+ 360 +
+
+
        conjure_ast::Range::Bounded(x, y) => Ok((x.to_owned(), y.to_owned())),
+
+
+
+ 207 +
+
+ +
+
+
        conjure_ast::Range::Single(x) => Ok((x.to_owned(), x.to_owned())),
+
+
+
+ 208 +
+
+ +
+
+
        #[allow(unreachable_patterns)]
+
+
+
+ 209 +
+
+ +
+
+
        x => Err(ModelFeatureNotSupported(format!("{:?}", x))),
+
+
+
+ 210 +
+
+ +
+
+
    }?;
+
+
+
+ 211 +
+
+ +
+
+

+            
+
+
+ 212 +
+
+ 360 +
+
+
    _try_add_var(
+
+
+
+ 213 +
+
+ 360 +
+
+
        str_name.to_owned(),
+
+
+
+ 214 +
+
+ 360 +
+
+
        minion_ast::VarDomain::Bound(low, high),
+
+
+
+ 215 +
+
+ 360 +
+
+
        minion_model,
+
+
+
+ 216 +
+
+ 360 +
+
+
    )
+
+
+
+ 217 +
+
+ 360 +
+
+
}
+
+
+
+ 218 +
+
+ +
+
+

+            
+
+
+ 219 +
+
+ 105 +
+
+
fn _parse_booldomain_var(
+
+
+
+ 220 +
+
+ 105 +
+
+
    name: &conjure_ast::Name,
+
+
+
+ 221 +
+
+ 105 +
+
+
    minion_model: &mut MinionModel,
+
+
+
+ 222 +
+
+ 105 +
+
+
) -> Result<(), SolverError> {
+
+
+
+ 223 +
+
+ 105 +
+
+
    let str_name = _name_to_string(name.to_owned());
+
+
+
+ 224 +
+
+ 105 +
+
+
    _try_add_var(
+
+
+
+ 225 +
+
+ 105 +
+
+
        str_name.to_owned(),
+
+
+
+ 226 +
+
+ 105 +
+
+
        minion_ast::VarDomain::Bool,
+
+
+
+ 227 +
+
+ 105 +
+
+
        minion_model,
+
+
+
+ 228 +
+
+ 105 +
+
+
    )
+
+
+
+ 229 +
+
+ 105 +
+
+
}
+
+
+
+ 230 +
+
+ +
+
+

+            
+
+
+ 231 +
+
+ 465 +
+
+
fn _try_add_var(
+
+
+
+ 232 +
+
+ 465 +
+
+
    name: minion_ast::VarName,
+
+
+
+ 233 +
+
+ 465 +
+
+
    domain: minion_ast::VarDomain,
+
+
+
+ 234 +
+
+ 465 +
+
+
    minion_model: &mut MinionModel,
+
+
+
+ 235 +
+
+ 465 +
+
+
) -> Result<(), SolverError> {
+
+
+
+ 236 +
+
+ 465 +
+
+
    minion_model
+
+
+
+ 237 +
+
+ 465 +
+
+
        .named_variables
+
+
+
+ 238 +
+
+ 465 +
+
+
        .add_var(name.clone(), domain)
+
+
+
+ 239 +
+
+ 465 +
+
+
        .ok_or(ModelInvalid(format!(
+
+
+
+ 240 +
+
+ 465 +
+
+
            "variable {:?} is defined twice",
+
+
+
+ 241 +
+
+ 465 +
+
+
            name
+
+
+
+ 242 +
+
+ 465 +
+
+
        )))
+
+
+
+ 243 +
+
+ 465 +
+
+
}
+
+
+
+ 244 +
+
+ +
+
+

+            
+
+
+ 245 +
+
+ 180 +
+
+
fn parse_exprs(
+
+
+
+ 246 +
+
+ 180 +
+
+
    conjure_model: &ConjureModel,
+
+
+
+ 247 +
+
+ 180 +
+
+
    minion_model: &mut MinionModel,
+
+
+
+ 248 +
+
+ 180 +
+
+
) -> Result<(), SolverError> {
+
+
+
+ 249 +
+
+ 675 +
+
+
    for expr in conjure_model.get_constraints_vec().iter() {
+
+
+
+ 250 +
+
+ 675 +
+
+
        parse_expr(expr.to_owned(), minion_model)?;
+
+
+
+ 251 +
+
+ +
+
+
    }
+
+
+
+ 252 +
+
+ 180 +
+
+
    Ok(())
+
+
+
+ 253 +
+
+ 180 +
+
+
}
+
+
+
+ 254 +
+
+ +
+
+

+            
+
+
+ 255 +
+
+ 675 +
+
+
fn parse_expr(
+
+
+
+ 256 +
+
+ 675 +
+
+
    expr: conjure_ast::Expression,
+
+
+
+ 257 +
+
+ 675 +
+
+
    minion_model: &mut MinionModel,
+
+
+
+ 258 +
+
+ 675 +
+
+
) -> Result<(), SolverError> {
+
+
+
+ 259 +
+
+ 675 +
+
+
    minion_model.constraints.push(read_expr(expr)?);
+
+
+
+ 260 +
+
+ 675 +
+
+
    Ok(())
+
+
+
+ 261 +
+
+ 675 +
+
+
}
+
+
+
+ 262 +
+
+ +
+
+

+            
+
+
+ 263 +
+
+ 1275 +
+
+
fn read_expr(expr: conjure_ast::Expression) -> Result<minion_ast::Constraint, SolverError> {
+
+
+
+ 264 +
+
+ 1275 +
+
+
    match expr {
+
+
+
+ 265 +
+
+ 45 +
+
+
        conjure_ast::Expression::SumLeq(_metadata, lhs, rhs) => Ok(minion_ast::Constraint::SumLeq(
+
+
+
+ 266 +
+
+ 45 +
+
+
            read_vars(lhs)?,
+
+
+
+ 267 +
+
+ 45 +
+
+
            read_var(*rhs)?,
+
+
+
+ 268 +
+
+ +
+
+
        )),
+
+
+
+ 269 +
+
+ 30 +
+
+
        conjure_ast::Expression::SumGeq(_metadata, lhs, rhs) => Ok(minion_ast::Constraint::SumGeq(
+
+
+
+ 270 +
+
+ 30 +
+
+
            read_vars(lhs)?,
+
+
+
+ 271 +
+
+ 30 +
+
+
            read_var(*rhs)?,
+
+
+
+ 272 +
+
+ +
+
+
        )),
+
+
+
+ 273 +
+
+ 870 +
+
+
        conjure_ast::Expression::Ineq(_metadata, a, b, c) => Ok(minion_ast::Constraint::Ineq(
+
+
+
+ 274 +
+
+ 870 +
+
+
            read_var(*a)?,
+
+
+
+ 275 +
+
+ 870 +
+
+
            read_var(*b)?,
+
+
+
+ 276 +
+
+ 870 +
+
+
            minion_ast::Constant::Integer(read_const(*c)?),
+
+
+
+ 277 +
+
+ +
+
+
        )),
+
+
+
+ 278 +
+
+ +
+
+
        conjure_ast::Expression::Neq(_metadata, a, b) => Ok(minion_ast::Constraint::AllDiff(vec![
+
+
+
+ 279 +
+
+ +
+
+
            read_var(*a)?,
+
+
+
+ 280 +
+
+ +
+
+
            read_var(*b)?,
+
+
+
+ 281 +
+
+ +
+
+
        ])),
+
+
+
+ 282 +
+
+ +
+
+
        // conjure_ast::Expression::DivEq(_metadata, a, b, c) => {
+
+
+
+ 283 +
+
+ +
+
+
        //     minion_model.constraints.push(minion_ast::Constraint::Div(
+
+
+
+ 284 +
+
+ +
+
+
        //         (read_var(*a)?, read_var(*b)?),
+
+
+
+ 285 +
+
+ +
+
+
        //         read_var(*c)?,
+
+
+
+ 286 +
+
+ +
+
+
        //     ));
+
+
+
+ 287 +
+
+ +
+
+
        //     Ok(())
+
+
+
+ 288 +
+
+ +
+
+
        // }
+
+
+
+ 289 +
+
+ 30 +
+
+
        conjure_ast::Expression::AllDiff(_metadata, vars) => {
+
+
+
+ 290 +
+
+ 30 +
+
+
            Ok(minion_ast::Constraint::AllDiff(read_vars(vars)?))
+
+
+
+ 291 +
+
+ +
+
+
        }
+
+
+
+ 292 +
+
+ 300 +
+
+
        conjure_ast::Expression::Or(_metadata, exprs) => Ok(minion_ast::Constraint::WatchedOr(
+
+
+
+ 293 +
+
+ 300 +
+
+
            exprs
+
+
+
+ 294 +
+
+ 300 +
+
+
                .iter()
+
+
+
+ 295 +
+
+ 600 +
+
+
                .map(|x| read_expr(x.to_owned()))
+
+
+
+ 296 +
+
+ 300 +
+
+
                .collect::<Result<Vec<minion_ast::Constraint>, SolverError>>()?,
+
+
+
+ 297 +
+
+ +
+
+
        )),
+
+
+
+ 298 +
+
+ +
+
+
        x => Err(ModelFeatureNotSupported(format!("{:?}", x))),
+
+
+
+ 299 +
+
+ +
+
+
    }
+
+
+
+ 300 +
+
+ 1275 +
+
+
}
+
+
+
+ 301 +
+
+ 105 +
+
+
fn read_vars(exprs: Vec<conjure_ast::Expression>) -> Result<Vec<minion_ast::Var>, SolverError> {
+
+
+
+ 302 +
+
+ 105 +
+
+
    let mut minion_vars: Vec<minion_ast::Var> = vec![];
+
+
+
+ 303 +
+
+ 390 +
+
+
    for expr in exprs {
+
+
+
+ 304 +
+
+ 285 +
+
+
        let minion_var = read_var(expr)?;
+
+
+
+ 305 +
+
+ 285 +
+
+
        minion_vars.push(minion_var);
+
+
+
+ 306 +
+
+ +
+
+
    }
+
+
+
+ 307 +
+
+ 105 +
+
+
    Ok(minion_vars)
+
+
+
+ 308 +
+
+ 105 +
+
+
}
+
+
+
+ 309 +
+
+ +
+
+

+            
+
+
+ 310 +
+
+ 2100 +
+
+
fn read_var(e: conjure_ast::Expression) -> Result<minion_ast::Var, SolverError> {
+
+
+
+ 311 +
+
+ 2100 +
+
+
    // a minion var is either a reference or a "var as const"
+
+
+
+ 312 +
+
+ 2100 +
+
+
    match _read_ref(e.clone()) {
+
+
+
+ 313 +
+
+ 1950 +
+
+
        Ok(name) => Ok(minion_ast::Var::NameRef(name)),
+
+
+
+ 314 +
+
+ 150 +
+
+
        Err(_) => match read_const(e) {
+
+
+
+ 315 +
+
+ 150 +
+
+
            Ok(n) => Ok(minion_ast::Var::ConstantAsVar(n)),
+
+
+
+ 316 +
+
+ +
+
+
            Err(x) => Err(x),
+
+
+
+ 317 +
+
+ +
+
+
        },
+
+
+
+ 318 +
+
+ +
+
+
    }
+
+
+
+ 319 +
+
+ 2100 +
+
+
}
+
+
+
+ 320 +
+
+ +
+
+

+            
+
+
+ 321 +
+
+ 2100 +
+
+
fn _read_ref(e: conjure_ast::Expression) -> Result<String, SolverError> {
+
+
+
+ 322 +
+
+ 2100 +
+
+
    let name = match e {
+
+
+
+ 323 +
+
+ 1950 +
+
+
        conjure_ast::Expression::Reference(_metadata, n) => Ok(n),
+
+
+
+ 324 +
+
+ 150 +
+
+
        x => Err(ModelInvalid(format!(
+
+
+
+ 325 +
+
+ 150 +
+
+
            "expected a reference, but got `{0:?}`",
+
+
+
+ 326 +
+
+ 150 +
+
+
            x
+
+
+
+ 327 +
+
+ 150 +
+
+
        ))),
+
+
+
+ 328 +
+
+ 150 +
+
+
    }?;
+
+
+
+ 329 +
+
+ +
+
+

+            
+
+
+ 330 +
+
+ 1950 +
+
+
    let str_name = _name_to_string(name);
+
+
+
+ 331 +
+
+ 1950 +
+
+
    Ok(str_name)
+
+
+
+ 332 +
+
+ 2100 +
+
+
}
+
+
+
+ 333 +
+
+ +
+
+

+            
+
+
+ 334 +
+
+ 1020 +
+
+
fn read_const(e: conjure_ast::Expression) -> Result<i32, SolverError> {
+
+
+
+ 335 +
+
+ 1020 +
+
+
    match e {
+
+
+
+ 336 +
+
+ 1020 +
+
+
        conjure_ast::Expression::Constant(_, conjure_ast::Constant::Int(n)) => Ok(n),
+
+
+
+ 337 +
+
+ +
+
+
        x => Err(ModelInvalid(format!(
+
+
+
+ 338 +
+
+ +
+
+
            "expected a constant, but got `{0:?}`",
+
+
+
+ 339 +
+
+ +
+
+
            x
+
+
+
+ 340 +
+
+ +
+
+
        ))),
+
+
+
+ 341 +
+
+ +
+
+
    }
+
+
+
+ 342 +
+
+ 1020 +
+
+
}
+
+
+
+ 343 +
+
+ +
+
+

+            
+
+
+ 344 +
+
+ 2415 +
+
+
fn _name_to_string(name: conjure_ast::Name) -> String {
+
+
+
+ 345 +
+
+ 2415 +
+
+
    match name {
+
+
+
+ 346 +
+
+ 1515 +
+
+
        conjure_ast::Name::UserName(x) => x,
+
+
+
+ 347 +
+
+ 900 +
+
+
        conjure_ast::Name::MachineName(x) => format!("__conjure_machine_name_{}", x),
+
+
+
+ 348 +
+
+ +
+
+
    }
+
+
+
+ 349 +
+
+ 2415 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/adaptors/sat_common.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/adaptors/sat_common.rs.html new file mode 100644 index 0000000000..1b123c09b6 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/adaptors/sat_common.rs.html @@ -0,0 +1,5225 @@ + + + + + Grcov report - sat_common.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
//! Common code for SAT adaptors.
+
+
+
+ 2 +
+
+ +
+
+
//! Primarily, this is CNF related code.
+
+
+
+ 3 +
+
+ +
+
+

+            
+
+
+ 4 +
+
+ +
+
+
use std::collections::HashMap;
+
+
+
+ 5 +
+
+ +
+
+

+            
+
+
+ 6 +
+
+ +
+
+
use thiserror::Error;
+
+
+
+ 7 +
+
+ +
+
+

+            
+
+
+ 8 +
+
+ +
+
+
use crate::{
+
+
+
+ 9 +
+
+ +
+
+
    ast as conjure_ast, solver::SolverError, solver::SolverError::*, Model as ConjureModel,
+
+
+
+ 10 +
+
+ +
+
+
};
+
+
+
+ 11 +
+
+ +
+
+
// (nd60, march 24) - i basically copied all this from @gskorokod's SAT implemention for the old
+
+
+
+ 12 +
+
+ +
+
+
// solver interface.
+
+
+
+ 13 +
+
+ +
+
+
use crate::metadata::Metadata;
+
+
+
+ 14 +
+
+ +
+
+

+            
+
+
+ 15 +
+
+ +
+
+
/// A representation of a model in CNF.
+
+
+
+ 16 +
+
+ +
+
+
///
+
+
+
+ 17 +
+
+ +
+
+
/// Expects Model to be in the Conjunctive Normal Form:
+
+
+
+ 18 +
+
+ +
+
+
///
+
+
+
+ 19 +
+
+ +
+
+
/// - All variables must be boolean
+
+
+
+ 20 +
+
+ +
+
+
/// - Expressions must be `Reference`, `Not(Reference)`, or `Or(Reference1, Not(Reference2), ...)`
+
+
+
+ 21 +
+
+ +
+
+
/// - The top level And() may contain nested Or()s. Any other nested expressions are not allowed.
+
+
+
+ 22 +
+
+ +
+
+
#[derive(Debug, Clone)]
+
+
+
+ 23 +
+
+ +
+
+
pub struct CNFModel {
+
+
+
+ 24 +
+
+ +
+
+
    pub clauses: Vec<Vec<i32>>,
+
+
+
+ 25 +
+
+ +
+
+
    variables: HashMap<conjure_ast::Name, i32>,
+
+
+
+ 26 +
+
+ +
+
+
    next_ind: i32,
+
+
+
+ 27 +
+
+ +
+
+
}
+
+
+
+ 28 +
+
+ +
+
+
impl CNFModel {
+
+
+
+ 29 +
+
+ +
+
+
    pub fn new() -> CNFModel {
+
+
+
+ 30 +
+
+ +
+
+
        CNFModel {
+
+
+
+ 31 +
+
+ +
+
+
            clauses: Vec::new(),
+
+
+
+ 32 +
+
+ +
+
+
            variables: HashMap::new(),
+
+
+
+ 33 +
+
+ +
+
+
            next_ind: 1,
+
+
+
+ 34 +
+
+ +
+
+
        }
+
+
+
+ 35 +
+
+ +
+
+
    }
+
+
+
+ 36 +
+
+ +
+
+

+            
+
+
+ 37 +
+
+ +
+
+
    pub fn from_conjure(conjure_model: ConjureModel) -> Result<CNFModel, SolverError> {
+
+
+
+ 38 +
+
+ +
+
+
        let mut ans: CNFModel = CNFModel::new();
+
+
+
+ 39 +
+
+ +
+
+

+            
+
+
+ 40 +
+
+ +
+
+
        for var in conjure_model.variables.keys() {
+
+
+
+ 41 +
+
+ +
+
+
            // Check that domain has the correct type
+
+
+
+ 42 +
+
+ +
+
+
            let decision_var = match conjure_model.variables.get(var) {
+
+
+
+ 43 +
+
+ +
+
+
                None => {
+
+
+
+ 44 +
+
+ +
+
+
                    return Err(ModelInvalid(format!("variable {:?} not found", var)));
+
+
+
+ 45 +
+
+ +
+
+
                }
+
+
+
+ 46 +
+
+ +
+
+
                Some(var) => var,
+
+
+
+ 47 +
+
+ +
+
+
            };
+
+
+
+ 48 +
+
+ +
+
+

+            
+
+
+ 49 +
+
+ +
+
+
            if decision_var.domain != conjure_ast::Domain::BoolDomain {
+
+
+
+ 50 +
+
+ +
+
+
                return Err(ModelFeatureNotSupported(format!(
+
+
+
+ 51 +
+
+ +
+
+
                    "variable {:?} is not BoolDomain",
+
+
+
+ 52 +
+
+ +
+
+
                    decision_var
+
+
+
+ 53 +
+
+ +
+
+
                )));
+
+
+
+ 54 +
+
+ +
+
+
            }
+
+
+
+ 55 +
+
+ +
+
+

+            
+
+
+ 56 +
+
+ +
+
+
            ans.add_variable(var);
+
+
+
+ 57 +
+
+ +
+
+
        }
+
+
+
+ 58 +
+
+ +
+
+

+            
+
+
+ 59 +
+
+ +
+
+
        for expr in conjure_model.get_constraints_vec() {
+
+
+
+ 60 +
+
+ +
+
+
            match ans.add_expression(&expr) {
+
+
+
+ 61 +
+
+ +
+
+
                Ok(_) => {}
+
+
+
+ 62 +
+
+ +
+
+
                Err(error) => {
+
+
+
+ 63 +
+
+ +
+
+
                    let message = format!("{:?}", error);
+
+
+
+ 64 +
+
+ +
+
+
                    return Err(ModelFeatureNotSupported(message));
+
+
+
+ 65 +
+
+ +
+
+
                }
+
+
+
+ 66 +
+
+ +
+
+
            }
+
+
+
+ 67 +
+
+ +
+
+
        }
+
+
+
+ 68 +
+
+ +
+
+

+            
+
+
+ 69 +
+
+ +
+
+
        Ok(ans)
+
+
+
+ 70 +
+
+ +
+
+
    }
+
+
+
+ 71 +
+
+ +
+
+

+            
+
+
+ 72 +
+
+ +
+
+
    /// Gets all the Conjure variables in the CNF.
+
+
+
+ 73 +
+
+ +
+
+
    #[allow(dead_code)] // It will be used once we actually run kissat
+
+
+
+ 74 +
+
+ +
+
+
    pub fn get_variables(&self) -> Vec<&conjure_ast::Name> {
+
+
+
+ 75 +
+
+ +
+
+
        let mut ans: Vec<&conjure_ast::Name> = Vec::new();
+
+
+
+ 76 +
+
+ +
+
+

+            
+
+
+ 77 +
+
+ +
+
+
        for key in self.variables.keys() {
+
+
+
+ 78 +
+
+ +
+
+
            ans.push(key);
+
+
+
+ 79 +
+
+ +
+
+
        }
+
+
+
+ 80 +
+
+ +
+
+

+            
+
+
+ 81 +
+
+ +
+
+
        ans
+
+
+
+ 82 +
+
+ +
+
+
    }
+
+
+
+ 83 +
+
+ +
+
+

+            
+
+
+ 84 +
+
+ +
+
+
    /// Gets the index of a Conjure variable.
+
+
+
+ 85 +
+
+ +
+
+
    pub fn get_index(&self, var: &conjure_ast::Name) -> Option<i32> {
+
+
+
+ 86 +
+
+ +
+
+
        return self.variables.get(var).copied();
+
+
+
+ 87 +
+
+ +
+
+
    }
+
+
+
+ 88 +
+
+ +
+
+

+            
+
+
+ 89 +
+
+ +
+
+
    /// Gets a Conjure variable by index.
+
+
+
+ 90 +
+
+ +
+
+
    pub fn get_name(&self, ind: i32) -> Option<&conjure_ast::Name> {
+
+
+
+ 91 +
+
+ +
+
+
        for key in self.variables.keys() {
+
+
+
+ 92 +
+
+ +
+
+
            let idx = self.get_index(key)?;
+
+
+
+ 93 +
+
+ +
+
+
            if idx == ind {
+
+
+
+ 94 +
+
+ +
+
+
                return Some(key);
+
+
+
+ 95 +
+
+ +
+
+
            }
+
+
+
+ 96 +
+
+ +
+
+
        }
+
+
+
+ 97 +
+
+ +
+
+

+            
+
+
+ 98 +
+
+ +
+
+
        None
+
+
+
+ 99 +
+
+ +
+
+
    }
+
+
+
+ 100 +
+
+ +
+
+

+            
+
+
+ 101 +
+
+ +
+
+
    /// Adds a new Conjure variable to the CNF representation.
+
+
+
+ 102 +
+
+ +
+
+
    pub fn add_variable(&mut self, var: &conjure_ast::Name) {
+
+
+
+ 103 +
+
+ +
+
+
        self.variables.insert(var.clone(), self.next_ind);
+
+
+
+ 104 +
+
+ +
+
+
        self.next_ind += 1;
+
+
+
+ 105 +
+
+ +
+
+
    }
+
+
+
+ 106 +
+
+ +
+
+

+            
+
+
+ 107 +
+
+ +
+
+
    /**
+
+
+
+ 108 +
+
+ +
+
+
     * Check if a Conjure variable or index is present in the CNF
+
+
+
+ 109 +
+
+ +
+
+
     */
+
+
+
+ 110 +
+
+ +
+
+
    pub fn has_variable<T: HasVariable>(&self, value: T) -> bool {
+
+
+
+ 111 +
+
+ +
+
+
        value.has_variable(self)
+
+
+
+ 112 +
+
+ +
+
+
    }
+
+
+
+ 113 +
+
+ +
+
+

+            
+
+
+ 114 +
+
+ +
+
+
    /**
+
+
+
+ 115 +
+
+ +
+
+
     * Add a new clause to the CNF. Must be a vector of indices in CNF format
+
+
+
+ 116 +
+
+ +
+
+
     */
+
+
+
+ 117 +
+
+ +
+
+
    pub fn add_clause(&mut self, vec: &Vec<i32>) -> Result<(), CNFError> {
+
+
+
+ 118 +
+
+ +
+
+
        for idx in vec {
+
+
+
+ 119 +
+
+ +
+
+
            if !self.has_variable(idx.abs()) {
+
+
+
+ 120 +
+
+ +
+
+
                return Err(CNFError::ClauseIndexNotFound(*idx));
+
+
+
+ 121 +
+
+ +
+
+
            }
+
+
+
+ 122 +
+
+ +
+
+
        }
+
+
+
+ 123 +
+
+ +
+
+
        self.clauses.push(vec.clone());
+
+
+
+ 124 +
+
+ +
+
+
        Ok(())
+
+
+
+ 125 +
+
+ +
+
+
    }
+
+
+
+ 126 +
+
+ +
+
+

+            
+
+
+ 127 +
+
+ +
+
+
    /**
+
+
+
+ 128 +
+
+ +
+
+
     * Add a new Conjure expression to the CNF. Must be a logical expression in CNF form
+
+
+
+ 129 +
+
+ +
+
+
     */
+
+
+
+ 130 +
+
+ +
+
+
    pub fn add_expression(&mut self, expr: &conjure_ast::Expression) -> Result<(), CNFError> {
+
+
+
+ 131 +
+
+ +
+
+
        for row in self.handle_expression(expr)? {
+
+
+
+ 132 +
+
+ +
+
+
            self.add_clause(&row)?;
+
+
+
+ 133 +
+
+ +
+
+
        }
+
+
+
+ 134 +
+
+ +
+
+
        Ok(())
+
+
+
+ 135 +
+
+ +
+
+
    }
+
+
+
+ 136 +
+
+ +
+
+

+            
+
+
+ 137 +
+
+ +
+
+
    /**
+
+
+
+ 138 +
+
+ +
+
+
     * Convert the CNF to a Conjure expression
+
+
+
+ 139 +
+
+ +
+
+
     */
+
+
+
+ 140 +
+
+ +
+
+
    #[allow(dead_code)] // It will be used once we actually run kissat
+
+
+
+ 141 +
+
+ +
+
+
    pub fn as_expression(&self) -> Result<conjure_ast::Expression, CNFError> {
+
+
+
+ 142 +
+
+ +
+
+
        let mut expr_clauses: Vec<conjure_ast::Expression> = Vec::new();
+
+
+
+ 143 +
+
+ +
+
+

+            
+
+
+ 144 +
+
+ +
+
+
        for clause in &self.clauses {
+
+
+
+ 145 +
+
+ +
+
+
            expr_clauses.push(self.clause_to_expression(clause)?);
+
+
+
+ 146 +
+
+ +
+
+
        }
+
+
+
+ 147 +
+
+ +
+
+

+            
+
+
+ 148 +
+
+ +
+
+
        Ok(conjure_ast::Expression::And(Metadata::new(), expr_clauses))
+
+
+
+ 149 +
+
+ +
+
+
    }
+
+
+
+ 150 +
+
+ +
+
+

+            
+
+
+ 151 +
+
+ +
+
+
    /**
+
+
+
+ 152 +
+
+ +
+
+
     * Convert a single clause to a Conjure expression
+
+
+
+ 153 +
+
+ +
+
+
     */
+
+
+
+ 154 +
+
+ +
+
+
    fn clause_to_expression(&self, clause: &Vec<i32>) -> Result<conjure_ast::Expression, CNFError> {
+
+
+
+ 155 +
+
+ +
+
+
        let mut ans: Vec<conjure_ast::Expression> = Vec::new();
+
+
+
+ 156 +
+
+ +
+
+

+            
+
+
+ 157 +
+
+ +
+
+
        for idx in clause {
+
+
+
+ 158 +
+
+ +
+
+
            match self.get_name(idx.abs()) {
+
+
+
+ 159 +
+
+ +
+
+
                None => return Err(CNFError::ClauseIndexNotFound(*idx)),
+
+
+
+ 160 +
+
+ +
+
+
                Some(name) => {
+
+
+
+ 161 +
+
+ +
+
+
                    if *idx > 0 {
+
+
+
+ 162 +
+
+ +
+
+
                        ans.push(conjure_ast::Expression::Reference(
+
+
+
+ 163 +
+
+ +
+
+
                            Metadata::new(),
+
+
+
+ 164 +
+
+ +
+
+
                            name.clone(),
+
+
+
+ 165 +
+
+ +
+
+
                        ));
+
+
+
+ 166 +
+
+ +
+
+
                    } else {
+
+
+
+ 167 +
+
+ +
+
+
                        let expression: conjure_ast::Expression =
+
+
+
+ 168 +
+
+ +
+
+
                            conjure_ast::Expression::Reference(Metadata::new(), name.clone());
+
+
+
+ 169 +
+
+ +
+
+
                        ans.push(conjure_ast::Expression::Not(
+
+
+
+ 170 +
+
+ +
+
+
                            Metadata::new(),
+
+
+
+ 171 +
+
+ +
+
+
                            Box::from(expression),
+
+
+
+ 172 +
+
+ +
+
+
                        ))
+
+
+
+ 173 +
+
+ +
+
+
                    }
+
+
+
+ 174 +
+
+ +
+
+
                }
+
+
+
+ 175 +
+
+ +
+
+
            }
+
+
+
+ 176 +
+
+ +
+
+
        }
+
+
+
+ 177 +
+
+ +
+
+

+            
+
+
+ 178 +
+
+ +
+
+
        Ok(conjure_ast::Expression::Or(Metadata::new(), ans))
+
+
+
+ 179 +
+
+ +
+
+
    }
+
+
+
+ 180 +
+
+ +
+
+

+            
+
+
+ 181 +
+
+ +
+
+
    /**
+
+
+
+ 182 +
+
+ +
+
+
     * Get the index for a Conjure Reference or return an error
+
+
+
+ 183 +
+
+ +
+
+
     * @see get_index
+
+
+
+ 184 +
+
+ +
+
+
     * @see conjure_ast::Expression::Reference
+
+
+
+ 185 +
+
+ +
+
+
     */
+
+
+
+ 186 +
+
+ +
+
+
    fn get_reference_index(&self, name: &conjure_ast::Name) -> Result<i32, CNFError> {
+
+
+
+ 187 +
+
+ +
+
+
        match self.get_index(name) {
+
+
+
+ 188 +
+
+ +
+
+
            None => Err(CNFError::VariableNameNotFound(name.clone())),
+
+
+
+ 189 +
+
+ +
+
+
            Some(ind) => Ok(ind),
+
+
+
+ 190 +
+
+ +
+
+
        }
+
+
+
+ 191 +
+
+ +
+
+
    }
+
+
+
+ 192 +
+
+ +
+
+

+            
+
+
+ 193 +
+
+ +
+
+
    /**
+
+
+
+ 194 +
+
+ +
+
+
     * Convert the contents of a single Reference to a row of the CNF format
+
+
+
+ 195 +
+
+ +
+
+
     * @see get_reference_index
+
+
+
+ 196 +
+
+ +
+
+
     * @see conjure_ast::Expression::Reference
+
+
+
+ 197 +
+
+ +
+
+
     */
+
+
+
+ 198 +
+
+ +
+
+
    fn handle_reference(&self, name: &conjure_ast::Name) -> Result<Vec<i32>, CNFError> {
+
+
+
+ 199 +
+
+ +
+
+
        Ok(vec![self.get_reference_index(name)?])
+
+
+
+ 200 +
+
+ +
+
+
    }
+
+
+
+ 201 +
+
+ +
+
+

+            
+
+
+ 202 +
+
+ +
+
+
    /**
+
+
+
+ 203 +
+
+ +
+
+
     * Convert the contents of a single Not() to CNF
+
+
+
+ 204 +
+
+ +
+
+
     */
+
+
+
+ 205 +
+
+ +
+
+
    fn handle_not(&self, expr: &conjure_ast::Expression) -> Result<Vec<i32>, CNFError> {
+
+
+
+ 206 +
+
+ +
+
+
        match expr {
+
+
+
+ 207 +
+
+ +
+
+
            // Expression inside the Not()
+
+
+
+ 208 +
+
+ +
+
+
            conjure_ast::Expression::Reference(_metadata, name) => {
+
+
+
+ 209 +
+
+ +
+
+
                Ok(vec![-self.get_reference_index(name)?])
+
+
+
+ 210 +
+
+ +
+
+
            }
+
+
+
+ 211 +
+
+ +
+
+
            _ => Err(CNFError::UnexpectedExpressionInsideNot(expr.clone())),
+
+
+
+ 212 +
+
+ +
+
+
        }
+
+
+
+ 213 +
+
+ +
+
+
    }
+
+
+
+ 214 +
+
+ +
+
+

+            
+
+
+ 215 +
+
+ +
+
+
    /**
+
+
+
+ 216 +
+
+ +
+
+
     * Convert the contents of a single Or() to a row of the CNF format
+
+
+
+ 217 +
+
+ +
+
+
     */
+
+
+
+ 218 +
+
+ +
+
+
    fn handle_or(&self, expressions: &Vec<conjure_ast::Expression>) -> Result<Vec<i32>, CNFError> {
+
+
+
+ 219 +
+
+ +
+
+
        let mut ans: Vec<i32> = Vec::new();
+
+
+
+ 220 +
+
+ +
+
+

+            
+
+
+ 221 +
+
+ +
+
+
        for expr in expressions {
+
+
+
+ 222 +
+
+ +
+
+
            let ret = self.handle_flat_expression(expr)?;
+
+
+
+ 223 +
+
+ +
+
+
            for ind in ret {
+
+
+
+ 224 +
+
+ +
+
+
                ans.push(ind);
+
+
+
+ 225 +
+
+ +
+
+
            }
+
+
+
+ 226 +
+
+ +
+
+
        }
+
+
+
+ 227 +
+
+ +
+
+

+            
+
+
+ 228 +
+
+ +
+
+
        Ok(ans)
+
+
+
+ 229 +
+
+ +
+
+
    }
+
+
+
+ 230 +
+
+ +
+
+

+            
+
+
+ 231 +
+
+ +
+
+
    /**
+
+
+
+ 232 +
+
+ +
+
+
     * Convert a single Reference, `Not` or `Or` into a clause of the CNF format
+
+
+
+ 233 +
+
+ +
+
+
     */
+
+
+
+ 234 +
+
+ +
+
+
    fn handle_flat_expression(
+
+
+
+ 235 +
+
+ +
+
+
        &self,
+
+
+
+ 236 +
+
+ +
+
+
        expression: &conjure_ast::Expression,
+
+
+
+ 237 +
+
+ +
+
+
    ) -> Result<Vec<i32>, CNFError> {
+
+
+
+ 238 +
+
+ +
+
+
        match expression {
+
+
+
+ 239 +
+
+ +
+
+
            conjure_ast::Expression::Reference(_metadata, name) => self.handle_reference(name),
+
+
+
+ 240 +
+
+ +
+
+
            conjure_ast::Expression::Not(_metadata, var_box) => self.handle_not(var_box),
+
+
+
+ 241 +
+
+ +
+
+
            conjure_ast::Expression::Or(_metadata, expressions) => self.handle_or(expressions),
+
+
+
+ 242 +
+
+ +
+
+
            _ => Err(CNFError::UnexpectedExpression(expression.clone())),
+
+
+
+ 243 +
+
+ +
+
+
        }
+
+
+
+ 244 +
+
+ +
+
+
    }
+
+
+
+ 245 +
+
+ +
+
+

+            
+
+
+ 246 +
+
+ +
+
+
    /**
+
+
+
+ 247 +
+
+ +
+
+
     * Convert a single And() into a vector of clauses in the CNF format
+
+
+
+ 248 +
+
+ +
+
+
     */
+
+
+
+ 249 +
+
+ +
+
+
    fn handle_and(
+
+
+
+ 250 +
+
+ +
+
+
        &self,
+
+
+
+ 251 +
+
+ +
+
+
        expressions: &Vec<conjure_ast::Expression>,
+
+
+
+ 252 +
+
+ +
+
+
    ) -> Result<Vec<Vec<i32>>, CNFError> {
+
+
+
+ 253 +
+
+ +
+
+
        let mut ans: Vec<Vec<i32>> = Vec::new();
+
+
+
+ 254 +
+
+ +
+
+

+            
+
+
+ 255 +
+
+ +
+
+
        for expression in expressions {
+
+
+
+ 256 +
+
+ +
+
+
            match expression {
+
+
+
+ 257 +
+
+ +
+
+
                conjure_ast::Expression::And(_metadata, _expressions) => {
+
+
+
+ 258 +
+
+ +
+
+
                    return Err(CNFError::NestedAnd(expression.clone()));
+
+
+
+ 259 +
+
+ +
+
+
                }
+
+
+
+ 260 +
+
+ +
+
+
                _ => {
+
+
+
+ 261 +
+
+ +
+
+
                    ans.push(self.handle_flat_expression(expression)?);
+
+
+
+ 262 +
+
+ +
+
+
                }
+
+
+
+ 263 +
+
+ +
+
+
            }
+
+
+
+ 264 +
+
+ +
+
+
        }
+
+
+
+ 265 +
+
+ +
+
+

+            
+
+
+ 266 +
+
+ +
+
+
        Ok(ans)
+
+
+
+ 267 +
+
+ +
+
+
    }
+
+
+
+ 268 +
+
+ +
+
+

+            
+
+
+ 269 +
+
+ +
+
+
    /**
+
+
+
+ 270 +
+
+ +
+
+
     * Convert a single Conjure expression into a vector of clauses of the CNF format
+
+
+
+ 271 +
+
+ +
+
+
     */
+
+
+
+ 272 +
+
+ +
+
+
    fn handle_expression(
+
+
+
+ 273 +
+
+ +
+
+
        &self,
+
+
+
+ 274 +
+
+ +
+
+
        expression: &conjure_ast::Expression,
+
+
+
+ 275 +
+
+ +
+
+
    ) -> Result<Vec<Vec<i32>>, CNFError> {
+
+
+
+ 276 +
+
+ +
+
+
        match expression {
+
+
+
+ 277 +
+
+ +
+
+
            conjure_ast::Expression::And(_metadata, expressions) => self.handle_and(expressions),
+
+
+
+ 278 +
+
+ +
+
+
            _ => Ok(vec![self.handle_flat_expression(expression)?]),
+
+
+
+ 279 +
+
+ +
+
+
        }
+
+
+
+ 280 +
+
+ +
+
+
    }
+
+
+
+ 281 +
+
+ +
+
+
}
+
+
+
+ 282 +
+
+ +
+
+

+            
+
+
+ 283 +
+
+ +
+
+
impl Default for CNFModel {
+
+
+
+ 284 +
+
+ +
+
+
    fn default() -> Self {
+
+
+
+ 285 +
+
+ +
+
+
        Self::new()
+
+
+
+ 286 +
+
+ +
+
+
    }
+
+
+
+ 287 +
+
+ +
+
+
}
+
+
+
+ 288 +
+
+ +
+
+

+            
+
+
+ 289 +
+
+ +
+
+
#[derive(Error, Debug)]
+
+
+
+ 290 +
+
+ +
+
+
pub enum CNFError {
+
+
+
+ 291 +
+
+ +
+
+
    #[error("Variable with name `{0}` not found")]
+
+
+
+ 292 +
+
+ +
+
+
    VariableNameNotFound(conjure_ast::Name),
+
+
+
+ 293 +
+
+ +
+
+

+            
+
+
+ 294 +
+
+ +
+
+
    #[error("Clause with index `{0}` not found")]
+
+
+
+ 295 +
+
+ +
+
+
    ClauseIndexNotFound(i32),
+
+
+
+ 296 +
+
+ +
+
+

+            
+
+
+ 297 +
+
+ +
+
+
    #[error("Unexpected Expression `{0}` inside Not(). Only Not(Reference) allowed!")]
+
+
+
+ 298 +
+
+ +
+
+
    UnexpectedExpressionInsideNot(conjure_ast::Expression),
+
+
+
+ 299 +
+
+ +
+
+

+            
+
+
+ 300 +
+
+ +
+
+
    #[error(
+
+
+
+ 301 +
+
+ +
+
+
        "Unexpected Expression `{0}` found. Only Reference, Not(Reference) and Or(...) allowed!"
+
+
+
+ 302 +
+
+ +
+
+
    )]
+
+
+
+ 303 +
+
+ +
+
+
    UnexpectedExpression(conjure_ast::Expression),
+
+
+
+ 304 +
+
+ +
+
+

+            
+
+
+ 305 +
+
+ +
+
+
    #[error("Unexpected nested And: {0}")]
+
+
+
+ 306 +
+
+ +
+
+
    NestedAnd(conjure_ast::Expression),
+
+
+
+ 307 +
+
+ +
+
+
}
+
+
+
+ 308 +
+
+ +
+
+

+            
+
+
+ 309 +
+
+ +
+
+
/// Helper trait for checking if a variable is present in the CNF polymorphically (i32 or conjure_ast::Name)
+
+
+
+ 310 +
+
+ +
+
+
pub trait HasVariable {
+
+
+
+ 311 +
+
+ +
+
+
    fn has_variable(self, cnf: &CNFModel) -> bool;
+
+
+
+ 312 +
+
+ +
+
+
}
+
+
+
+ 313 +
+
+ +
+
+

+            
+
+
+ 314 +
+
+ +
+
+
impl HasVariable for i32 {
+
+
+
+ 315 +
+
+ +
+
+
    fn has_variable(self, cnf: &CNFModel) -> bool {
+
+
+
+ 316 +
+
+ +
+
+
        return cnf.get_name(self).is_some();
+
+
+
+ 317 +
+
+ +
+
+
    }
+
+
+
+ 318 +
+
+ +
+
+
}
+
+
+
+ 319 +
+
+ +
+
+

+            
+
+
+ 320 +
+
+ +
+
+
impl HasVariable for &conjure_ast::Name {
+
+
+
+ 321 +
+
+ +
+
+
    fn has_variable(self, cnf: &CNFModel) -> bool {
+
+
+
+ 322 +
+
+ +
+
+
        cnf.get_index(self).is_some()
+
+
+
+ 323 +
+
+ +
+
+
    }
+
+
+
+ 324 +
+
+ +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/index.html new file mode 100644 index 0000000000..7218e293e6 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/index.html @@ -0,0 +1,98 @@ + + + + + Grcov report - crates/conjure_core/src/solver + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
mod.rs + + 71.34% + + + 71.34% + + 112 / 157 + 13.04%15 / 115
model_modifier.rs + + 0% + + + 0% + + 0 / 6 + 0%0 / 6
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/mod.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/mod.rs.html new file mode 100644 index 0000000000..c169d88ce7 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/mod.rs.html @@ -0,0 +1,6937 @@ + + + + + Grcov report - mod.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
//! A high-level API for interacting with constraints solvers.
+
+
+
+ 2 +
+
+ +
+
+
//!
+
+
+
+ 3 +
+
+ +
+
+
//! This module provides a consistent, solver-independent API for interacting with constraints
+
+
+
+ 4 +
+
+ +
+
+
//! solvers. It also provides incremental solving support, and the returning of run stats from
+
+
+
+ 5 +
+
+ +
+
+
//! solvers.
+
+
+
+ 6 +
+
+ +
+
+
//!
+
+
+
+ 7 +
+
+ +
+
+
//! -----
+
+
+
+ 8 +
+
+ +
+
+
//!
+
+
+
+ 9 +
+
+ +
+
+
//! - [Solver<Adaptor>] provides the API for interacting with constraints solvers.
+
+
+
+ 10 +
+
+ +
+
+
//!
+
+
+
+ 11 +
+
+ +
+
+
//! - The [SolverAdaptor] trait controls how solving actually occurs and handles translation
+
+
+
+ 12 +
+
+ +
+
+
//! between the [Solver] type and a specific solver.
+
+
+
+ 13 +
+
+ +
+
+
//!
+
+
+
+ 14 +
+
+ +
+
+
//! - [adaptors] contains all implemented solver adaptors.
+
+
+
+ 15 +
+
+ +
+
+
//!
+
+
+
+ 16 +
+
+ +
+
+
//! - The [model_modifier] submodule defines types to help with incremental solving / changing a
+
+
+
+ 17 +
+
+ +
+
+
//!   model during search. The entrypoint for incremental solving is the [Solver<A,ModelLoaded>::solve_mut]
+
+
+
+ 18 +
+
+ +
+
+
//!   function.
+
+
+
+ 19 +
+
+ +
+
+
//!
+
+
+
+ 20 +
+
+ +
+
+
//! # Examples
+
+
+
+ 21 +
+
+ +
+
+
//!
+
+
+
+ 22 +
+
+ +
+
+
//! ## A Successful Minion Model
+
+
+
+ 23 +
+
+ +
+
+
//!
+
+
+
+ 24 +
+
+ +
+
+
//! ```rust
+
+
+
+ 25 +
+
+ 1 +
+
+
//! use std::sync::{Arc,Mutex};
+
+
+
+ 26 +
+
+ 1 +
+
+
//! use conjure_core::parse::get_example_model;
+
+
+
+ 27 +
+
+ 1 +
+
+
//! use conjure_core::rule_engine::resolve_rule_sets;
+
+
+
+ 28 +
+
+ 1 +
+
+
//! use conjure_core::rule_engine::rewrite_model;
+
+
+
+ 29 +
+
+ 1 +
+
+
//! use conjure_core::solver::{adaptors, Solver, SolverAdaptor};
+
+
+
+ 30 +
+
+ 1 +
+
+
//! use conjure_core::solver::states::ModelLoaded;
+
+
+
+ 31 +
+
+ 1 +
+
+
//! use conjure_core::solver::SolverFamily;
+
+
+
+ 32 +
+
+ 1 +
+
+
//!
+
+
+
+ 33 +
+
+ 1 +
+
+
//! // Define and rewrite a model for minion.
+
+
+
+ 34 +
+
+ 1 +
+
+
//! let model = get_example_model("bool-03").unwrap();
+
+
+
+ 35 +
+
+ 1 +
+
+
//! let rule_sets = resolve_rule_sets(SolverFamily::Minion, &vec!["Constant"]).unwrap();
+
+
+
+ 36 +
+
+ 1 +
+
+
//! let model = rewrite_model(&model,&rule_sets).unwrap();
+
+
+
+ 37 +
+
+ 1 +
+
+
//!
+
+
+
+ 38 +
+
+ 1 +
+
+
//!
+
+
+
+ 39 +
+
+ 1 +
+
+
//! // Solve using Minion.
+
+
+
+ 40 +
+
+ 1 +
+
+
//! let solver = Solver::new(adaptors::Minion::new());
+
+
+
+ 41 +
+
+ 1 +
+
+
//! let solver: Solver<adaptors::Minion,ModelLoaded> = solver.load_model(model).unwrap();
+
+
+
+ 42 +
+
+ 1 +
+
+
//!
+
+
+
+ 43 +
+
+ 1 +
+
+
//! // In this example, we will count solutions.
+
+
+
+ 44 +
+
+ 1 +
+
+
//! //
+
+
+
+ 45 +
+
+ 1 +
+
+
//! // The solver interface is designed to allow adaptors to use multiple-threads / processes if
+
+
+
+ 46 +
+
+ 1 +
+
+
//! // necessary. Therefore, the callback type requires all variables inside it to have a static
+
+
+
+ 47 +
+
+ 1 +
+
+
//! // lifetime and to implement Send (i.e. the variable can be safely shared between theads).
+
+
+
+ 48 +
+
+ 1 +
+
+
//! //
+
+
+
+ 49 +
+
+ 1 +
+
+
//! // We use Arc<Mutex<T>> to create multiple references to a threadsafe mutable
+
+
+
+ 50 +
+
+ 1 +
+
+
//! // variable of type T.
+
+
+
+ 51 +
+
+ 1 +
+
+
//! //
+
+
+
+ 52 +
+
+ 1 +
+
+
//! // Using the move |x| ... closure syntax, we move one of these references into the closure.
+
+
+
+ 53 +
+
+ 1 +
+
+
//! // Note that a normal closure borrow variables from the parent so is not
+
+
+
+ 54 +
+
+ 1 +
+
+
//! // thread-safe.
+
+
+
+ 55 +
+
+ 1 +
+
+
//!
+
+
+
+ 56 +
+
+ 1 +
+
+
//! let counter_ref = Arc::new(Mutex::new(0));
+
+
+
+ 57 +
+
+ 1 +
+
+
//! let counter_ref_2 = counter_ref.clone();
+
+
+
+ 58 +
+
+ 1 +
+
+
//! solver.solve(Box::new(move |_| {
+
+
+
+ 59 +
+
+ 2 +
+
+
//!   let mut counter = (*counter_ref_2).lock().unwrap();
+
+
+
+ 60 +
+
+ 2 +
+
+
//!   *counter += 1;
+
+
+
+ 61 +
+
+ 2 +
+
+
//!   true
+
+
+
+ 62 +
+
+ 2 +
+
+
//!   }));
+
+
+
+ 63 +
+
+ 2 +
+
+
//!
+
+
+
+ 64 +
+
+ 1 +
+
+
//! let mut counter = (*counter_ref).lock().unwrap();
+
+
+
+ 65 +
+
+ 1 +
+
+
//! assert_eq!(*counter,2);
+
+
+
+ 66 +
+
+ 1 +
+
+
//! ```
+
+
+
+ 67 +
+
+ 1 +
+
+
//!
+
+
+
+ 68 +
+
+ +
+
+
//!
+
+
+
+ 69 +
+
+ +
+
+

+            
+
+
+ 70 +
+
+ +
+
+
// # Implementing Solver interfaces
+
+
+
+ 71 +
+
+ +
+
+
//
+
+
+
+ 72 +
+
+ +
+
+
// Solver interfaces can only be implemented inside this module, due to the SolverAdaptor crate
+
+
+
+ 73 +
+
+ +
+
+
// being sealed.
+
+
+
+ 74 +
+
+ +
+
+
//
+
+
+
+ 75 +
+
+ +
+
+
// To add support for a solver, implement the `SolverAdaptor` trait in a submodule.
+
+
+
+ 76 +
+
+ +
+
+
//
+
+
+
+ 77 +
+
+ +
+
+
// If incremental solving support is required, also implement a new `ModelModifier`. If this is not
+
+
+
+ 78 +
+
+ +
+
+
// required, all `ModelModifier` instances required by the SolverAdaptor trait can be replaced with
+
+
+
+ 79 +
+
+ +
+
+
// NotModifiable.
+
+
+
+ 80 +
+
+ +
+
+
//
+
+
+
+ 81 +
+
+ +
+
+
// For more details, see the docstrings for SolverAdaptor, ModelModifier, and NotModifiable.
+
+
+
+ 82 +
+
+ +
+
+

+            
+
+
+ 83 +
+
+ +
+
+
#![allow(dead_code)]
+
+
+
+ 84 +
+
+ +
+
+
#![allow(unused)]
+
+
+
+ 85 +
+
+ +
+
+
#![allow(clippy::manual_non_exhaustive)]
+
+
+
+ 86 +
+
+ +
+
+

+            
+
+
+ 87 +
+
+ +
+
+
use std::any::Any;
+
+
+
+ 88 +
+
+ +
+
+
use std::cell::OnceCell;
+
+
+
+ 89 +
+
+ +
+
+
use std::collections::HashMap;
+
+
+
+ 90 +
+
+ +
+
+
use std::error::Error;
+
+
+
+ 91 +
+
+ +
+
+
use std::fmt::{Debug, Display};
+
+
+
+ 92 +
+
+ +
+
+
use std::rc::Rc;
+
+
+
+ 93 +
+
+ +
+
+
use std::sync::{Arc, RwLock};
+
+
+
+ 94 +
+
+ +
+
+
use std::time::Instant;
+
+
+
+ 95 +
+
+ +
+
+

+            
+
+
+ 96 +
+
+ +
+
+
use schemars::JsonSchema;
+
+
+
+ 97 +
+
+ +
+
+
use serde::{Deserialize, Serialize};
+
+
+
+ 98 +
+
+ +
+
+
use strum_macros::{Display, EnumIter, EnumString};
+
+
+
+ 99 +
+
+ +
+
+
use thiserror::Error;
+
+
+
+ 100 +
+
+ +
+
+

+            
+
+
+ 101 +
+
+ +
+
+
use crate::ast::{Constant, Name};
+
+
+
+ 102 +
+
+ +
+
+
use crate::context::Context;
+
+
+
+ 103 +
+
+ +
+
+
use crate::stats::SolverStats;
+
+
+
+ 104 +
+
+ +
+
+
use crate::Model;
+
+
+
+ 105 +
+
+ +
+
+

+            
+
+
+ 106 +
+
+ +
+
+
use self::model_modifier::ModelModifier;
+
+
+
+ 107 +
+
+ +
+
+
use self::states::*;
+
+
+
+ 108 +
+
+ +
+
+

+            
+
+
+ 109 +
+
+ +
+
+
pub mod adaptors;
+
+
+
+ 110 +
+
+ +
+
+
pub mod model_modifier;
+
+
+
+ 111 +
+
+ +
+
+

+            
+
+
+ 112 +
+
+ +
+
+
#[doc(hidden)]
+
+
+
+ 113 +
+
+ +
+
+
mod private;
+
+
+
+ 114 +
+
+ +
+
+

+            
+
+
+ 115 +
+
+ +
+
+
pub mod states;
+
+
+
+ 116 +
+
+ +
+
+

+            
+
+
+ 117 +
+
+ +
+
+
#[derive(
+
+
+
+ 118 +
+
+ +
+
+
    Debug,
+
+
+
+ 119 +
+
+ +
+
+
    EnumString,
+
+
+
+ 120 +
+
+ +
+
+
    EnumIter,
+
+
+
+ 121 +
+
+ +
+
+
    Display,
+
+
+
+ 122 +
+
+ +
+
+
    PartialEq,
+
+
+
+ 123 +
+
+ +
+
+
    Eq,
+
+
+
+ 124 +
+
+ +
+
+
    Hash,
+
+
+
+ 125 +
+
+ +
+
+
    Clone,
+
+
+
+ 126 +
+
+ +
+
+
    Copy,
+
+
+
+ 127 +
+
+ +
+
+
    Serialize,
+
+
+
+ 128 +
+
+ +
+
+
    Deserialize,
+
+
+
+ 129 +
+
+ +
+
+
    JsonSchema,
+
+
+
+ 130 +
+
+ +
+
+
)]
+
+
+
+ 131 +
+
+ +
+
+

+            
+
+
+ 132 +
+
+ +
+
+
pub enum SolverFamily {
+
+
+
+ 133 +
+
+ +
+
+
    SAT,
+
+
+
+ 134 +
+
+ +
+
+
    Minion,
+
+
+
+ 135 +
+
+ +
+
+
}
+
+
+
+ 136 +
+
+ +
+
+

+            
+
+
+ 137 +
+
+ +
+
+
/// The type for user-defined callbacks for use with [Solver].
+
+
+
+ 138 +
+
+ +
+
+
///
+
+
+
+ 139 +
+
+ +
+
+
/// Note that this enforces thread safety
+
+
+
+ 140 +
+
+ +
+
+
pub type SolverCallback = Box<dyn Fn(HashMap<Name, Constant>) -> bool + Send>;
+
+
+
+ 141 +
+
+ +
+
+
pub type SolverMutCallback =
+
+
+
+ 142 +
+
+ +
+
+
    Box<dyn Fn(HashMap<Name, Constant>, Box<dyn ModelModifier>) -> bool + Send>;
+
+
+
+ 143 +
+
+ +
+
+

+            
+
+
+ 144 +
+
+ +
+
+
/// A common interface for calling underlying solver APIs inside a [`Solver`].
+
+
+
+ 145 +
+
+ +
+
+
///
+
+
+
+ 146 +
+
+ +
+
+
/// Implementations of this trait aren't directly callable and should be used through [`Solver`] .
+
+
+
+ 147 +
+
+ +
+
+
///
+
+
+
+ 148 +
+
+ +
+
+
/// The below documentation lists the formal requirements that all implementations of
+
+
+
+ 149 +
+
+ +
+
+
/// [`SolverAdaptor`] should follow - **see the top level module documentation and [`Solver`] for
+
+
+
+ 150 +
+
+ +
+
+
/// usage details.**
+
+
+
+ 151 +
+
+ +
+
+
///
+
+
+
+ 152 +
+
+ +
+
+
/// # Encapsulation
+
+
+
+ 153 +
+
+ +
+
+
///  
+
+
+
+ 154 +
+
+ +
+
+
///  The [`SolverAdaptor`] trait **must** only be implemented inside a submodule of this one,
+
+
+
+ 155 +
+
+ +
+
+
///  and **should** only be called through [`Solver`].
+
+
+
+ 156 +
+
+ +
+
+
///
+
+
+
+ 157 +
+
+ +
+
+
/// The `private::Sealed` trait and `private::Internal` type enforce these requirements by only
+
+
+
+ 158 +
+
+ +
+
+
/// allowing trait implementations and calling of methods of SolverAdaptor to occur inside this
+
+
+
+ 159 +
+
+ +
+
+
/// module.
+
+
+
+ 160 +
+
+ +
+
+
///
+
+
+
+ 161 +
+
+ +
+
+
/// # Thread Safety
+
+
+
+ 162 +
+
+ +
+
+
///
+
+
+
+ 163 +
+
+ +
+
+
/// Multiple instances of [`Solver`] can be run in parallel across multiple threads.
+
+
+
+ 164 +
+
+ +
+
+
///
+
+
+
+ 165 +
+
+ +
+
+
/// [`Solver`] provides no concurrency control or thread-safety; therefore, adaptors **must**
+
+
+
+ 166 +
+
+ +
+
+
/// ensure that multiple instances of themselves can be ran in parallel. This applies to all
+
+
+
+ 167 +
+
+ +
+
+
/// stages of solving including having two active `solve()` calls happening at a time, loading
+
+
+
+ 168 +
+
+ +
+
+
/// a model while another is mid-solve, loading two models at once, etc.
+
+
+
+ 169 +
+
+ +
+
+
///
+
+
+
+ 170 +
+
+ +
+
+
/// A [SolverAdaptor] **may** use whatever threading or process model it likes underneath the hood,
+
+
+
+ 171 +
+
+ +
+
+
/// as long as it obeys the above.
+
+
+
+ 172 +
+
+ +
+
+
///
+
+
+
+ 173 +
+
+ +
+
+
/// Method calls **should** block instead of erroring where possible.
+
+
+
+ 174 +
+
+ +
+
+
///
+
+
+
+ 175 +
+
+ +
+
+
/// Underlying solvers that only have one instance per process (such as Minion) **should** block
+
+
+
+ 176 +
+
+ +
+
+
/// (eg. using a [`Mutex<()>`](`std::sync::Mutex`)) to run calls to
+
+
+
+ 177 +
+
+ +
+
+
/// [`Solver<A,ModelLoaded>::solve()`] and [`Solver<A,ModelLoaded>::solve_mut()`] sequentially.
+
+
+
+ 178 +
+
+ +
+
+
pub trait SolverAdaptor: private::Sealed + Any {
+
+
+
+ 179 +
+
+ +
+
+
    /// Runs the solver on the given model.
+
+
+
+ 180 +
+
+ +
+
+
    ///
+
+
+
+ 181 +
+
+ +
+
+
    /// Implementations of this function **must** call the user provided callback whenever a solution
+
+
+
+ 182 +
+
+ +
+
+
    /// is found. If the user callback returns `true`, search should continue, if the user callback
+
+
+
+ 183 +
+
+ +
+
+
    /// returns `false`, search should terminate.
+
+
+
+ 184 +
+
+ +
+
+
    ///
+
+
+
+ 185 +
+
+ +
+
+
    /// # Returns
+
+
+
+ 186 +
+
+ +
+
+
    ///
+
+
+
+ 187 +
+
+ +
+
+
    /// If the solver terminates without crashing a [SolveSuccess] struct **must** returned. The
+
+
+
+ 188 +
+
+ +
+
+
    /// value of [SearchStatus] can be used to denote whether the underlying solver completed its
+
+
+
+ 189 +
+
+ +
+
+
    /// search or not. The latter case covers most non-crashing "failure" cases including user
+
+
+
+ 190 +
+
+ +
+
+
    /// termination, timeouts, etc.
+
+
+
+ 191 +
+
+ +
+
+
    ///
+
+
+
+ 192 +
+
+ +
+
+
    /// To help populate [SearchStatus], it may be helpful to implement counters that track if the
+
+
+
+ 193 +
+
+ +
+
+
    /// user callback has been called yet, and its return value. This information makes it is
+
+
+
+ 194 +
+
+ +
+
+
    /// possible to distinguish between the most common search statuses:
+
+
+
+ 195 +
+
+ +
+
+
    /// [SearchComplete::HasSolutions], [SearchComplete::NoSolutions], and
+
+
+
+ 196 +
+
+ +
+
+
    /// [SearchIncomplete::UserTerminated].
+
+
+
+ 197 +
+
+ +
+
+
    fn solve(
+
+
+
+ 198 +
+
+ +
+
+
        &mut self,
+
+
+
+ 199 +
+
+ +
+
+
        callback: SolverCallback,
+
+
+
+ 200 +
+
+ +
+
+
        _: private::Internal,
+
+
+
+ 201 +
+
+ +
+
+
    ) -> Result<SolveSuccess, SolverError>;
+
+
+
+ 202 +
+
+ +
+
+

+            
+
+
+ 203 +
+
+ +
+
+
    /// Runs the solver on the given model, allowing modification of the model through a
+
+
+
+ 204 +
+
+ +
+
+
    /// [`ModelModifier`].
+
+
+
+ 205 +
+
+ +
+
+
    ///
+
+
+
+ 206 +
+
+ +
+
+
    /// Implementations of this function **must** return [`OpNotSupported`](`ModificationFailure::OpNotSupported`)
+
+
+
+ 207 +
+
+ +
+
+
    /// if modifying the model mid-search is not supported.
+
+
+
+ 208 +
+
+ +
+
+
    ///
+
+
+
+ 209 +
+
+ +
+
+
    /// Otherwise, this should work in the same way as [`solve`](SolverAdaptor::solve).
+
+
+
+ 210 +
+
+ +
+
+
    fn solve_mut(
+
+
+
+ 211 +
+
+ +
+
+
        &mut self,
+
+
+
+ 212 +
+
+ +
+
+
        callback: SolverMutCallback,
+
+
+
+ 213 +
+
+ +
+
+
        _: private::Internal,
+
+
+
+ 214 +
+
+ +
+
+
    ) -> Result<SolveSuccess, SolverError>;
+
+
+
+ 215 +
+
+ +
+
+
    fn load_model(&mut self, model: Model, _: private::Internal) -> Result<(), SolverError>;
+
+
+
+ 216 +
+
+ 56 +
+
+
    fn init_solver(&mut self, _: private::Internal) {}
+
+
+
+ 217 +
+
+ +
+
+

+            
+
+
+ 218 +
+
+ +
+
+
    /// Get the solver family that this solver adaptor belongs to
+
+
+
+ 219 +
+
+ +
+
+
    fn get_family(&self) -> SolverFamily;
+
+
+
+ 220 +
+
+ +
+
+

+            
+
+
+ 221 +
+
+ +
+
+
    /// Gets the name of the solver adaptor for pretty printing.
+
+
+
+ 222 +
+
+ +
+
+
    fn get_name(&self) -> Option<String> {
+
+
+
+ 223 +
+
+ +
+
+
        None
+
+
+
+ 224 +
+
+ +
+
+
    }
+
+
+
+ 225 +
+
+ +
+
+

+            
+
+
+ 226 +
+
+ +
+
+
    /// Adds the solver adaptor name and family (if they exist) to the given stats object.
+
+
+
+ 227 +
+
+ 56 +
+
+
    fn add_adaptor_info_to_stats(&self, stats: SolverStats) -> SolverStats {
+
+
+
+ 228 +
+
+ 56 +
+
+
        SolverStats {
+
+
+
+ 229 +
+
+ 56 +
+
+
            solver_adaptor: self.get_name(),
+
+
+
+ 230 +
+
+ 56 +
+
+
            solver_family: Some(self.get_family()),
+
+
+
+ 231 +
+
+ 56 +
+
+
            ..stats
+
+
+
+ 232 +
+
+ 56 +
+
+
        }
+
+
+
+ 233 +
+
+ 56 +
+
+
    }
+
+
+
+ 234 +
+
+ +
+
+
}
+
+
+
+ 235 +
+
+ +
+
+

+            
+
+
+ 236 +
+
+ +
+
+
/// An abstract representation of a constraints solver.
+
+
+
+ 237 +
+
+ +
+
+
///
+
+
+
+ 238 +
+
+ +
+
+
/// [Solver] provides a common interface for interacting with a constraint solver. It also
+
+
+
+ 239 +
+
+ +
+
+
/// abstracts over solver-specific datatypes, handling the translation to/from [conjure_core::ast]
+
+
+
+ 240 +
+
+ +
+
+
/// types for a model and its solutions.
+
+
+
+ 241 +
+
+ +
+
+
///
+
+
+
+ 242 +
+
+ +
+
+
/// Details of how a model is solved is specified by the [SolverAdaptor]. This includes: the
+
+
+
+ 243 +
+
+ +
+
+
/// underlying solver used, the translation of the model to a solver compatible form, how solutions
+
+
+
+ 244 +
+
+ +
+
+
/// are translated back to [conjure_core::ast] types, and how incremental solving is implemented.
+
+
+
+ 245 +
+
+ +
+
+
/// As such, there may be multiple [SolverAdaptor] implementations for a single underlying solver:
+
+
+
+ 246 +
+
+ +
+
+
/// e.g. one adaptor may give solutions in a representation close to the solvers, while another may
+
+
+
+ 247 +
+
+ +
+
+
/// attempt to rewrite it back into Essence.
+
+
+
+ 248 +
+
+ +
+
+
///
+
+
+
+ 249 +
+
+ +
+
+
#[derive(Clone)]
+
+
+
+ 250 +
+
+ +
+
+
pub struct Solver<A: SolverAdaptor, State: SolverState = Init> {
+
+
+
+ 251 +
+
+ +
+
+
    state: State,
+
+
+
+ 252 +
+
+ +
+
+
    adaptor: A,
+
+
+
+ 253 +
+
+ +
+
+
    context: Option<Arc<RwLock<Context<'static>>>>,
+
+
+
+ 254 +
+
+ +
+
+
}
+
+
+
+ 255 +
+
+ +
+
+

+            
+
+
+ 256 +
+
+ +
+
+
impl<Adaptor: SolverAdaptor> Solver<Adaptor> {
+
+
+
+ 257 +
+
+ 56 +
+
+
    pub fn new(solver_adaptor: Adaptor) -> Solver<Adaptor> {
+
+
+
+ 258 +
+
+ 56 +
+
+
        let mut solver = Solver {
+
+
+
+ 259 +
+
+ 56 +
+
+
            state: Init,
+
+
+
+ 260 +
+
+ 56 +
+
+
            adaptor: solver_adaptor,
+
+
+
+ 261 +
+
+ 56 +
+
+
            context: None,
+
+
+
+ 262 +
+
+ 56 +
+
+
        };
+
+
+
+ 263 +
+
+ 56 +
+
+

+            
+
+
+ 264 +
+
+ 56 +
+
+
        solver.adaptor.init_solver(private::Internal);
+
+
+
+ 265 +
+
+ 56 +
+
+
        solver
+
+
+
+ 266 +
+
+ 56 +
+
+
    }
+
+
+
+ 267 +
+
+ +
+
+

+            
+
+
+ 268 +
+
+ +
+
+
    pub fn get_family(&self) -> SolverFamily {
+
+
+
+ 269 +
+
+ +
+
+
        self.adaptor.get_family()
+
+
+
+ 270 +
+
+ +
+
+
    }
+
+
+
+ 271 +
+
+ +
+
+
}
+
+
+
+ 272 +
+
+ +
+
+

+            
+
+
+ 273 +
+
+ +
+
+
impl<A: SolverAdaptor> Solver<A, Init> {
+
+
+
+ 274 +
+
+ 56 +
+
+
    pub fn load_model(mut self, model: Model) -> Result<Solver<A, ModelLoaded>, SolverError> {
+
+
+
+ 275 +
+
+ 56 +
+
+
        let solver_model = &mut self.adaptor.load_model(model.clone(), private::Internal)?;
+
+
+
+ 276 +
+
+ 56 +
+
+
        Ok(Solver {
+
+
+
+ 277 +
+
+ 56 +
+
+
            state: ModelLoaded,
+
+
+
+ 278 +
+
+ 56 +
+
+
            adaptor: self.adaptor,
+
+
+
+ 279 +
+
+ 56 +
+
+
            context: Some(model.context.clone()),
+
+
+
+ 280 +
+
+ 56 +
+
+
        })
+
+
+
+ 281 +
+
+ 56 +
+
+
    }
+
+
+
+ 282 +
+
+ +
+
+
}
+
+
+
+ 283 +
+
+ +
+
+

+            
+
+
+ 284 +
+
+ +
+
+
impl<A: SolverAdaptor> Solver<A, ModelLoaded> {
+
+
+
+ 285 +
+
+ 56 +
+
+
    pub fn solve(
+
+
+
+ 286 +
+
+ 56 +
+
+
        mut self,
+
+
+
+ 287 +
+
+ 56 +
+
+
        callback: SolverCallback,
+
+
+
+ 288 +
+
+ 56 +
+
+
    ) -> Result<Solver<A, ExecutionSuccess>, SolverError> {
+
+
+
+ 289 +
+
+ 56 +
+
+
        #[allow(clippy::unwrap_used)]
+
+
+
+ 290 +
+
+ 56 +
+
+
        let start_time = Instant::now();
+
+
+
+ 291 +
+
+ 56 +
+
+

+            
+
+
+ 292 +
+
+ 56 +
+
+
        #[allow(clippy::unwrap_used)]
+
+
+
+ 293 +
+
+ 56 +
+
+
        let result = self.adaptor.solve(callback, private::Internal);
+
+
+
+ 294 +
+
+ 56 +
+
+

+            
+
+
+ 295 +
+
+ 56 +
+
+
        let duration = start_time.elapsed();
+
+
+
+ 296 +
+
+ 56 +
+
+

+            
+
+
+ 297 +
+
+ 56 +
+
+
        match result {
+
+
+
+ 298 +
+
+ 56 +
+
+
            Ok(x) => {
+
+
+
+ 299 +
+
+ 56 +
+
+
                let stats = self
+
+
+
+ 300 +
+
+ 56 +
+
+
                    .adaptor
+
+
+
+ 301 +
+
+ 56 +
+
+
                    .add_adaptor_info_to_stats(x.stats)
+
+
+
+ 302 +
+
+ 56 +
+
+
                    .with_timings(duration.as_secs_f64());
+
+
+
+ 303 +
+
+ 56 +
+
+

+            
+
+
+ 304 +
+
+ 56 +
+
+
                Ok(Solver {
+
+
+
+ 305 +
+
+ 56 +
+
+
                    adaptor: self.adaptor,
+
+
+
+ 306 +
+
+ 56 +
+
+
                    state: ExecutionSuccess {
+
+
+
+ 307 +
+
+ 56 +
+
+
                        stats,
+
+
+
+ 308 +
+
+ 56 +
+
+
                        status: x.status,
+
+
+
+ 309 +
+
+ 56 +
+
+
                        _sealed: private::Internal,
+
+
+
+ 310 +
+
+ 56 +
+
+
                    },
+
+
+
+ 311 +
+
+ 56 +
+
+
                    context: self.context,
+
+
+
+ 312 +
+
+ 56 +
+
+
                })
+
+
+
+ 313 +
+
+ +
+
+
            }
+
+
+
+ 314 +
+
+ +
+
+
            Err(x) => Err(x),
+
+
+
+ 315 +
+
+ +
+
+
        }
+
+
+
+ 316 +
+
+ 56 +
+
+
    }
+
+
+
+ 317 +
+
+ +
+
+

+            
+
+
+ 318 +
+
+ +
+
+
    pub fn solve_mut(
+
+
+
+ 319 +
+
+ +
+
+
        mut self,
+
+
+
+ 320 +
+
+ +
+
+
        callback: SolverMutCallback,
+
+
+
+ 321 +
+
+ +
+
+
    ) -> Result<Solver<A, ExecutionSuccess>, SolverError> {
+
+
+
+ 322 +
+
+ +
+
+
        #[allow(clippy::unwrap_used)]
+
+
+
+ 323 +
+
+ +
+
+
        let start_time = Instant::now();
+
+
+
+ 324 +
+
+ +
+
+

+            
+
+
+ 325 +
+
+ +
+
+
        #[allow(clippy::unwrap_used)]
+
+
+
+ 326 +
+
+ +
+
+
        let result = self.adaptor.solve_mut(callback, private::Internal);
+
+
+
+ 327 +
+
+ +
+
+

+            
+
+
+ 328 +
+
+ +
+
+
        let duration = start_time.elapsed();
+
+
+
+ 329 +
+
+ +
+
+

+            
+
+
+ 330 +
+
+ +
+
+
        match result {
+
+
+
+ 331 +
+
+ +
+
+
            Ok(x) => {
+
+
+
+ 332 +
+
+ +
+
+
                let stats = self
+
+
+
+ 333 +
+
+ +
+
+
                    .adaptor
+
+
+
+ 334 +
+
+ +
+
+
                    .add_adaptor_info_to_stats(x.stats)
+
+
+
+ 335 +
+
+ +
+
+
                    .with_timings(duration.as_secs_f64());
+
+
+
+ 336 +
+
+ +
+
+

+            
+
+
+ 337 +
+
+ +
+
+
                Ok(Solver {
+
+
+
+ 338 +
+
+ +
+
+
                    adaptor: self.adaptor,
+
+
+
+ 339 +
+
+ +
+
+
                    state: ExecutionSuccess {
+
+
+
+ 340 +
+
+ +
+
+
                        stats,
+
+
+
+ 341 +
+
+ +
+
+
                        status: x.status,
+
+
+
+ 342 +
+
+ +
+
+
                        _sealed: private::Internal,
+
+
+
+ 343 +
+
+ +
+
+
                    },
+
+
+
+ 344 +
+
+ +
+
+
                    context: self.context,
+
+
+
+ 345 +
+
+ +
+
+
                })
+
+
+
+ 346 +
+
+ +
+
+
            }
+
+
+
+ 347 +
+
+ +
+
+
            Err(x) => Err(x),
+
+
+
+ 348 +
+
+ +
+
+
        }
+
+
+
+ 349 +
+
+ +
+
+
    }
+
+
+
+ 350 +
+
+ +
+
+
}
+
+
+
+ 351 +
+
+ +
+
+

+            
+
+
+ 352 +
+
+ +
+
+
impl<A: SolverAdaptor> Solver<A, ExecutionSuccess> {
+
+
+
+ 353 +
+
+ 45 +
+
+
    pub fn stats(&self) -> SolverStats {
+
+
+
+ 354 +
+
+ 45 +
+
+
        self.state.stats.clone()
+
+
+
+ 355 +
+
+ 45 +
+
+
    }
+
+
+
+ 356 +
+
+ +
+
+

+            
+
+
+ 357 +
+
+ +
+
+
    // Saves this solvers stats to the global context as a "solver run"
+
+
+
+ 358 +
+
+ 45 +
+
+
    pub fn save_stats_to_context(&self) {
+
+
+
+ 359 +
+
+ 45 +
+
+
        #[allow(clippy::unwrap_used)]
+
+
+
+ 360 +
+
+ 45 +
+
+
        #[allow(clippy::expect_used)]
+
+
+
+ 361 +
+
+ 45 +
+
+
        self.context
+
+
+
+ 362 +
+
+ 45 +
+
+
            .as_ref()
+
+
+
+ 363 +
+
+ 45 +
+
+
            .expect("")
+
+
+
+ 364 +
+
+ 45 +
+
+
            .write()
+
+
+
+ 365 +
+
+ 45 +
+
+
            .unwrap()
+
+
+
+ 366 +
+
+ 45 +
+
+
            .stats
+
+
+
+ 367 +
+
+ 45 +
+
+
            .add_solver_run(self.stats());
+
+
+
+ 368 +
+
+ 45 +
+
+
    }
+
+
+
+ 369 +
+
+ +
+
+

+            
+
+
+ 370 +
+
+ +
+
+
    pub fn wall_time_s(&self) -> f64 {
+
+
+
+ 371 +
+
+ +
+
+
        self.stats().conjure_solver_wall_time_s
+
+
+
+ 372 +
+
+ +
+
+
    }
+
+
+
+ 373 +
+
+ +
+
+
}
+
+
+
+ 374 +
+
+ +
+
+

+            
+
+
+ 375 +
+
+ +
+
+
/// Errors returned by [Solver] on failure.
+
+
+
+ 376 +
+
+ +
+
+
#[non_exhaustive]
+
+
+
+ 377 +
+
+ +
+
+
#[derive(Debug, Error, Clone)]
+
+
+
+ 378 +
+
+ +
+
+
pub enum SolverError {
+
+
+
+ 379 +
+
+ +
+
+
    #[error("operation not implemented yet: {0}")]
+
+
+
+ 380 +
+
+ +
+
+
    OpNotImplemented(String),
+
+
+
+ 381 +
+
+ +
+
+

+            
+
+
+ 382 +
+
+ +
+
+
    #[error("operation not supported: {0}")]
+
+
+
+ 383 +
+
+ +
+
+
    OpNotSupported(String),
+
+
+
+ 384 +
+
+ +
+
+

+            
+
+
+ 385 +
+
+ +
+
+
    #[error("model feature not supported: {0}")]
+
+
+
+ 386 +
+
+ +
+
+
    ModelFeatureNotSupported(String),
+
+
+
+ 387 +
+
+ +
+
+

+            
+
+
+ 388 +
+
+ +
+
+
    #[error("model feature not implemented yet: {0}")]
+
+
+
+ 389 +
+
+ +
+
+
    ModelFeatureNotImplemented(String),
+
+
+
+ 390 +
+
+ +
+
+

+            
+
+
+ 391 +
+
+ +
+
+
    // use for semantics / type errors, use the above for syntax
+
+
+
+ 392 +
+
+ +
+
+
    #[error("model invalid: {0}")]
+
+
+
+ 393 +
+
+ +
+
+
    ModelInvalid(String),
+
+
+
+ 394 +
+
+ +
+
+

+            
+
+
+ 395 +
+
+ +
+
+
    #[error("error during solver execution: not implemented: {0}")]
+
+
+
+ 396 +
+
+ +
+
+
    RuntimeNotImplemented(String),
+
+
+
+ 397 +
+
+ +
+
+

+            
+
+
+ 398 +
+
+ +
+
+
    #[error("error during solver execution: {0}")]
+
+
+
+ 399 +
+
+ +
+
+
    Runtime(String),
+
+
+
+ 400 +
+
+ +
+
+
}
+
+
+
+ 401 +
+
+ +
+
+

+            
+
+
+ 402 +
+
+ +
+
+
/// Returned from [SolverAdaptor] when solving is successful.
+
+
+
+ 403 +
+
+ +
+
+
pub struct SolveSuccess {
+
+
+
+ 404 +
+
+ +
+
+
    stats: SolverStats,
+
+
+
+ 405 +
+
+ +
+
+
    status: SearchStatus,
+
+
+
+ 406 +
+
+ +
+
+
}
+
+
+
+ 407 +
+
+ +
+
+

+            
+
+
+ 408 +
+
+ +
+
+
pub enum SearchStatus {
+
+
+
+ 409 +
+
+ +
+
+
    /// The search was complete (i.e. the solver found all possible solutions)
+
+
+
+ 410 +
+
+ +
+
+
    Complete(SearchComplete),
+
+
+
+ 411 +
+
+ +
+
+
    /// The search was incomplete (i.e. it was terminated before all solutions were found)
+
+
+
+ 412 +
+
+ +
+
+
    Incomplete(SearchIncomplete),
+
+
+
+ 413 +
+
+ +
+
+
}
+
+
+
+ 414 +
+
+ +
+
+

+            
+
+
+ 415 +
+
+ +
+
+
#[non_exhaustive]
+
+
+
+ 416 +
+
+ +
+
+
pub enum SearchIncomplete {
+
+
+
+ 417 +
+
+ +
+
+
    Timeout,
+
+
+
+ 418 +
+
+ +
+
+
    UserTerminated,
+
+
+
+ 419 +
+
+ +
+
+
    #[doc(hidden)]
+
+
+
+ 420 +
+
+ +
+
+
    /// This variant should not be matched - it exists to simulate non-exhaustiveness of this enum.
+
+
+
+ 421 +
+
+ +
+
+
    __NonExhaustive,
+
+
+
+ 422 +
+
+ +
+
+
}
+
+
+
+ 423 +
+
+ +
+
+

+            
+
+
+ 424 +
+
+ +
+
+
#[non_exhaustive]
+
+
+
+ 425 +
+
+ +
+
+
pub enum SearchComplete {
+
+
+
+ 426 +
+
+ +
+
+
    HasSolutions,
+
+
+
+ 427 +
+
+ +
+
+
    NoSolutions,
+
+
+
+ 428 +
+
+ +
+
+
    #[doc(hidden)]
+
+
+
+ 429 +
+
+ +
+
+
    /// This variant should not be matched - it exists to simulate non-exhaustiveness of this enum.
+
+
+
+ 430 +
+
+ +
+
+
    __NonExhaustive,
+
+
+
+ 431 +
+
+ +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/model_modifier.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/model_modifier.rs.html new file mode 100644 index 0000000000..822c99f08e --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/solver/model_modifier.rs.html @@ -0,0 +1,905 @@ + + + + + Grcov report - model_modifier.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
//! Modifying a model during search.
+
+
+
+ 2 +
+
+ +
+
+
//!
+
+
+
+ 3 +
+
+ +
+
+
//! Incremental solving can be triggered for a solverthrough the
+
+
+
+ 4 +
+
+ +
+
+
//! [`Solver::solve_mut`] method.
+
+
+
+ 5 +
+
+ +
+
+
//!
+
+
+
+ 6 +
+
+ +
+
+
//! This gives access to a [`ModelModifier`] in the solution retrieval callback.
+
+
+
+ 7 +
+
+ +
+
+

+            
+
+
+ 8 +
+
+ +
+
+
use crate::ast::{Domain, Expression, Name};
+
+
+
+ 9 +
+
+ +
+
+

+            
+
+
+ 10 +
+
+ +
+
+
use super::private;
+
+
+
+ 11 +
+
+ +
+
+
use super::Solver;
+
+
+
+ 12 +
+
+ +
+
+

+            
+
+
+ 13 +
+
+ +
+
+
/// A ModelModifier provides an interface to modify a model during solving.
+
+
+
+ 14 +
+
+ +
+
+
///
+
+
+
+ 15 +
+
+ +
+
+
/// Modifications are defined in terms of Conjure AST nodes, so must be translated to a solver
+
+
+
+ 16 +
+
+ +
+
+
/// specfic form before use.
+
+
+
+ 17 +
+
+ +
+
+
///
+
+
+
+ 18 +
+
+ +
+
+
/// It is implementation defined whether these constraints can be given at high level and passed
+
+
+
+ 19 +
+
+ +
+
+
/// through the rewriter, or only low-level solver constraints are supported.
+
+
+
+ 20 +
+
+ +
+
+
///
+
+
+
+ 21 +
+
+ +
+
+
/// See also: [`Solver::solve_mut`].
+
+
+
+ 22 +
+
+ +
+
+
pub trait ModelModifier: private::Sealed {
+
+
+
+ 23 +
+
+ +
+
+
    fn add_constraint(&self, constraint: Expression) -> Result<(), ModificationFailure> {
+
+
+
+ 24 +
+
+ +
+
+
        Err(ModificationFailure::OpNotSupported)
+
+
+
+ 25 +
+
+ +
+
+
    }
+
+
+
+ 26 +
+
+ +
+
+

+            
+
+
+ 27 +
+
+ +
+
+
    fn add_variable(&self, name: Name, domain: Domain) -> Result<(), ModificationFailure> {
+
+
+
+ 28 +
+
+ +
+
+
        Err(ModificationFailure::OpNotSupported)
+
+
+
+ 29 +
+
+ +
+
+
    }
+
+
+
+ 30 +
+
+ +
+
+
}
+
+
+
+ 31 +
+
+ +
+
+

+            
+
+
+ 32 +
+
+ +
+
+
/// A [`ModelModifier`] for a solver that does not support incremental solving. Returns
+
+
+
+ 33 +
+
+ +
+
+
/// [`OperationNotSupported`](`ModificationFailure::OperationNotSupported`) for all operations.
+
+
+
+ 34 +
+
+ +
+
+
pub struct NotModifiable;
+
+
+
+ 35 +
+
+ +
+
+

+            
+
+
+ 36 +
+
+ +
+
+
impl private::Sealed for NotModifiable {}
+
+
+
+ 37 +
+
+ +
+
+
impl ModelModifier for NotModifiable {}
+
+
+
+ 38 +
+
+ +
+
+

+            
+
+
+ 39 +
+
+ +
+
+
/// The requested modification to the model has failed.
+
+
+
+ 40 +
+
+ +
+
+
#[non_exhaustive]
+
+
+
+ 41 +
+
+ +
+
+
pub enum ModificationFailure {
+
+
+
+ 42 +
+
+ +
+
+
    /// The desired operation is not supported for this solver adaptor.
+
+
+
+ 43 +
+
+ +
+
+
    OpNotSupported,
+
+
+
+ 44 +
+
+ +
+
+

+            
+
+
+ 45 +
+
+ +
+
+
    /// The desired operation is supported by this solver adaptor, but has not been
+
+
+
+ 46 +
+
+ +
+
+
    /// implemented yet.
+
+
+
+ 47 +
+
+ +
+
+
    OpNotImplemented,
+
+
+
+ 48 +
+
+ +
+
+

+            
+
+
+ 49 +
+
+ +
+
+
    // The arguments given to the operation are invalid.
+
+
+
+ 50 +
+
+ +
+
+
    ArgsInvalid(anyhow::Error),
+
+
+
+ 51 +
+
+ +
+
+

+            
+
+
+ 52 +
+
+ +
+
+
    /// An unspecified error has occurred.
+
+
+
+ 53 +
+
+ +
+
+
    Error(anyhow::Error),
+
+
+
+ 54 +
+
+ +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/stats/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/stats/index.html new file mode 100644 index 0000000000..b581689fc2 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/stats/index.html @@ -0,0 +1,98 @@ + + + + + Grcov report - crates/conjure_core/src/stats + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
mod.rs + + 50% + + + 50% + + 3 / 6 + 16.67%1 / 6
solver_stats.rs + + 100% + + + 100% + + 6 / 6 + 33.33%1 / 3
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/stats/mod.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/stats/mod.rs.html new file mode 100644 index 0000000000..fd2da01b07 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/stats/mod.rs.html @@ -0,0 +1,425 @@ + + + + + Grcov report - mod.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
mod solver_stats;
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
use schemars::JsonSchema;
+
+
+
+ 4 +
+
+ +
+
+
use serde::Serialize;
+
+
+
+ 5 +
+
+ +
+
+
use serde_with::skip_serializing_none;
+
+
+
+ 6 +
+
+ +
+
+
pub use solver_stats::SolverStats;
+
+
+
+ 7 +
+
+ +
+
+

+            
+
+
+ 8 +
+
+ +
+
+
#[allow(dead_code)]
+
+
+
+ 9 +
+
+ +
+
+
#[skip_serializing_none]
+
+
+
+ 10 +
+
+ +
+
+
#[derive(Default, Serialize, Clone, JsonSchema)]
+
+
+
+ 11 +
+
+ +
+
+
#[serde(rename_all = "camelCase")]
+
+
+
+ 12 +
+
+ +
+
+
pub struct Stats {
+
+
+
+ 13 +
+
+ +
+
+
    pub solver_runs: Vec<SolverStats>,
+
+
+
+ 14 +
+
+ +
+
+
}
+
+
+
+ 15 +
+
+ +
+
+

+            
+
+
+ 16 +
+
+ +
+
+
impl Stats {
+
+
+
+ 17 +
+
+ +
+
+
    pub fn new() -> Stats {
+
+
+
+ 18 +
+
+ +
+
+
        Default::default()
+
+
+
+ 19 +
+
+ +
+
+
    }
+
+
+
+ 20 +
+
+ +
+
+

+            
+
+
+ 21 +
+
+ 135 +
+
+
    pub fn add_solver_run(&mut self, solver_stats: SolverStats) {
+
+
+
+ 22 +
+
+ 135 +
+
+
        self.solver_runs.push(solver_stats);
+
+
+
+ 23 +
+
+ 135 +
+
+
    }
+
+
+
+ 24 +
+
+ +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/stats/solver_stats.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/stats/solver_stats.rs.html new file mode 100644 index 0000000000..b0da0c75b0 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_core/src/stats/solver_stats.rs.html @@ -0,0 +1,665 @@ + + + + + Grcov report - solver_stats.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use schemars::JsonSchema;
+
+
+
+ 2 +
+
+ +
+
+
use serde::Serialize;
+
+
+
+ 3 +
+
+ +
+
+
use serde_with::skip_serializing_none;
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ +
+
+
use crate::solver::SolverFamily;
+
+
+
+ 6 +
+
+ +
+
+

+            
+
+
+ 7 +
+
+ +
+
+
#[skip_serializing_none]
+
+
+
+ 8 +
+
+ +
+
+
#[derive(Default, Serialize, Clone, JsonSchema)]
+
+
+
+ 9 +
+
+ +
+
+
#[serde(rename_all = "camelCase")]
+
+
+
+ 10 +
+
+ +
+
+
#[allow(dead_code)]
+
+
+
+ 11 +
+
+ +
+
+
// Statistics for a run of a solver.
+
+
+
+ 12 +
+
+ +
+
+
pub struct SolverStats {
+
+
+
+ 13 +
+
+ +
+
+
    #[serde(rename = "conjureSolverWallTime_s")]
+
+
+
+ 14 +
+
+ +
+
+
    /// Wall time as measured by Conjure-Oxide (not the solver).
+
+
+
+ 15 +
+
+ +
+
+
    pub conjure_solver_wall_time_s: f64,
+
+
+
+ 16 +
+
+ +
+
+

+            
+
+
+ 17 +
+
+ +
+
+
    // This is set by Solver, not SolverAdaptor
+
+
+
+ 18 +
+
+ +
+
+
    /// The solver family used for this run.
+
+
+
+ 19 +
+
+ +
+
+
    pub solver_family: Option<SolverFamily>,
+
+
+
+ 20 +
+
+ +
+
+

+            
+
+
+ 21 +
+
+ +
+
+
    /// The solver adaptor used for this run.
+
+
+
+ 22 +
+
+ +
+
+
    pub solver_adaptor: Option<String>,
+
+
+
+ 23 +
+
+ +
+
+

+            
+
+
+ 24 +
+
+ +
+
+
    // NOTE (niklasdewally): these fields are copied from the list in Savile Row
+
+
+
+ 25 +
+
+ +
+
+
    pub nodes: Option<u64>,
+
+
+
+ 26 +
+
+ +
+
+
    pub satisfiable: Option<bool>,
+
+
+
+ 27 +
+
+ +
+
+
    pub sat_vars: Option<u64>,
+
+
+
+ 28 +
+
+ +
+
+
    pub sat_clauses: Option<u64>,
+
+
+
+ 29 +
+
+ +
+
+
}
+
+
+
+ 30 +
+
+ +
+
+

+            
+
+
+ 31 +
+
+ +
+
+
impl SolverStats {
+
+
+
+ 32 +
+
+ +
+
+
    // Adds the conjure_solver_wall_time_s to the stats.
+
+
+
+ 33 +
+
+ 180 +
+
+
    pub fn with_timings(self, wall_time_s: f64) -> SolverStats {
+
+
+
+ 34 +
+
+ 180 +
+
+
        SolverStats {
+
+
+
+ 35 +
+
+ 180 +
+
+
            conjure_solver_wall_time_s: wall_time_s,
+
+
+
+ 36 +
+
+ 180 +
+
+
            ..self.clone()
+
+
+
+ 37 +
+
+ 180 +
+
+
        }
+
+
+
+ 38 +
+
+ 180 +
+
+
    }
+
+
+
+ 39 +
+
+ +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_macros/src/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_macros/src/index.html new file mode 100644 index 0000000000..d5f87632c6 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_macros/src/index.html @@ -0,0 +1,74 @@ + + + + + Grcov report - crates/conjure_macros/src + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
lib.rs + + 94.96% + + + 94.96% + + 113 / 119 + 55.88%19 / 34
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_macros/src/lib.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_macros/src/lib.rs.html new file mode 100644 index 0000000000..348072185d --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/conjure_macros/src/lib.rs.html @@ -0,0 +1,2937 @@ + + + + + Grcov report - lib.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use proc_macro::TokenStream;
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
use proc_macro2::Span;
+
+
+
+ 4 +
+
+ +
+
+
use quote::quote;
+
+
+
+ 5 +
+
+ +
+
+
use syn::punctuated::Punctuated;
+
+
+
+ 6 +
+
+ +
+
+
use syn::token::Comma;
+
+
+
+ 7 +
+
+ +
+
+
use syn::{
+
+
+
+ 8 +
+
+ +
+
+
    parenthesized, parse::Parse, parse::ParseStream, parse_macro_input, Ident, ItemFn, LitInt,
+
+
+
+ 9 +
+
+ +
+
+
    LitStr, Path, Result,
+
+
+
+ 10 +
+
+ +
+
+
};
+
+
+
+ 11 +
+
+ +
+
+

+            
+
+
+ 12 +
+
+ +
+
+
#[derive(Debug)]
+
+
+
+ 13 +
+
+ +
+
+
struct RuleSetAndPriority {
+
+
+
+ 14 +
+
+ +
+
+
    rule_set: LitStr,
+
+
+
+ 15 +
+
+ +
+
+
    priority: LitInt,
+
+
+
+ 16 +
+
+ +
+
+
}
+
+
+
+ 17 +
+
+ +
+
+

+            
+
+
+ 18 +
+
+ +
+
+
impl Parse for RuleSetAndPriority {
+
+
+
+ 19 +
+
+ 169 +
+
+
    fn parse(input: ParseStream) -> Result<Self> {
+
+
+
+ 20 +
+
+ 169 +
+
+
        let content;
+
+
+
+ 21 +
+
+ 169 +
+
+
        parenthesized!(content in input);
+
+
+
+ 22 +
+
+ 169 +
+
+
        let rule_set: LitStr = content.parse()?;
+
+
+
+ 23 +
+
+ 169 +
+
+
        let _: Comma = content.parse()?;
+
+
+
+ 24 +
+
+ 169 +
+
+
        let priority: LitInt = content.parse()?;
+
+
+
+ 25 +
+
+ 169 +
+
+
        Ok(RuleSetAndPriority { rule_set, priority })
+
+
+
+ 26 +
+
+ 169 +
+
+
    }
+
+
+
+ 27 +
+
+ +
+
+
}
+
+
+
+ 28 +
+
+ +
+
+

+            
+
+
+ 29 +
+
+ +
+
+
#[derive(Debug)]
+
+
+
+ 30 +
+
+ +
+
+
struct RegisterRuleArgs {
+
+
+
+ 31 +
+
+ +
+
+
    pub rule_sets: Vec<RuleSetAndPriority>,
+
+
+
+ 32 +
+
+ +
+
+
}
+
+
+
+ 33 +
+
+ +
+
+

+            
+
+
+ 34 +
+
+ +
+
+
impl Parse for RegisterRuleArgs {
+
+
+
+ 35 +
+
+ 171 +
+
+
    fn parse(input: ParseStream) -> Result<Self> {
+
+
+
+ 36 +
+
+ 171 +
+
+
        let rule_sets = Punctuated::<RuleSetAndPriority, Comma>::parse_terminated(input)?;
+
+
+
+ 37 +
+
+ 171 +
+
+
        Ok(RegisterRuleArgs {
+
+
+
+ 38 +
+
+ 171 +
+
+
            rule_sets: rule_sets.into_iter().collect(),
+
+
+
+ 39 +
+
+ 171 +
+
+
        })
+
+
+
+ 40 +
+
+ 171 +
+
+
    }
+
+
+
+ 41 +
+
+ +
+
+
}
+
+
+
+ 42 +
+
+ +
+
+

+            
+
+
+ 43 +
+
+ +
+
+
/**
+
+
+
+ 44 +
+
+ +
+
+
 * Register a rule with the given rule sets and priorities.
+
+
+
+ 45 +
+
+ +
+
+
 */
+
+
+
+ 46 +
+
+ +
+
+
#[proc_macro_attribute]
+
+
+
+ 47 +
+
+ 171 +
+
+
pub fn register_rule(arg_tokens: TokenStream, item: TokenStream) -> TokenStream {
+
+
+
+ 48 +
+
+ 171 +
+
+
    let func = parse_macro_input!(item as ItemFn);
+
+
+
+ 49 +
+
+ 171 +
+
+
    let rule_ident = &func.sig.ident;
+
+
+
+ 50 +
+
+ 171 +
+
+
    let static_name = format!("CONJURE_GEN_RULE_{}", rule_ident).to_uppercase();
+
+
+
+ 51 +
+
+ 171 +
+
+
    let static_ident = Ident::new(&static_name, rule_ident.span());
+
+
+
+ 52 +
+
+ +
+
+

+            
+
+
+ 53 +
+
+ 171 +
+
+
    let args = parse_macro_input!(arg_tokens as RegisterRuleArgs);
+
+
+
+ 54 +
+
+ 171 +
+
+
    let rule_sets = args
+
+
+
+ 55 +
+
+ 171 +
+
+
        .rule_sets
+
+
+
+ 56 +
+
+ 171 +
+
+
        .iter()
+
+
+
+ 57 +
+
+ 171 +
+
+
        .map(|rule_set| {
+
+
+
+ 58 +
+
+ 169 +
+
+
            let rule_set_name = &rule_set.rule_set;
+
+
+
+ 59 +
+
+ 169 +
+
+
            let priority = &rule_set.priority;
+
+
+
+ 60 +
+
+ 169 +
+
+
            quote! {
+
+
+
+ 61 +
+
+ 169 +
+
+
                (#rule_set_name, #priority as u8)
+
+
+
+ 62 +
+
+ 169 +
+
+
            }
+
+
+
+ 63 +
+
+ 171 +
+
+
        })
+
+
+
+ 64 +
+
+ 171 +
+
+
        .collect::<Vec<_>>();
+
+
+
+ 65 +
+
+ +
+
+

+            
+
+
+ 66 +
+
+ 171 +
+
+
    let expanded = quote! {
+
+
+
+ 67 +
+
+ 171 +
+
+
        #func
+
+
+
+ 68 +
+
+ 171 +
+
+

+            
+
+
+ 69 +
+
+ 171 +
+
+
        use ::conjure_core::rule_engine::_dependencies::*; // ToDo idk if we need to explicitly do that?
+
+
+
+ 70 +
+
+ 171 +
+
+

+            
+
+
+ 71 +
+
+ 171 +
+
+
        #[::conjure_core::rule_engine::_dependencies::distributed_slice(::conjure_core::rule_engine::RULES_DISTRIBUTED_SLICE)]
+
+
+
+ 72 +
+
+ 171 +
+
+
        pub static #static_ident: ::conjure_core::rule_engine::Rule<'static> = ::conjure_core::rule_engine::Rule {
+
+
+
+ 73 +
+
+ 171 +
+
+
            name: stringify!(#rule_ident),
+
+
+
+ 74 +
+
+ 171 +
+
+
            application: #rule_ident,
+
+
+
+ 75 +
+
+ 171 +
+
+
            rule_sets: &[#(#rule_sets),*],
+
+
+
+ 76 +
+
+ 171 +
+
+
        };
+
+
+
+ 77 +
+
+ 171 +
+
+
    };
+
+
+
+ 78 +
+
+ +
+
+

+            
+
+
+ 79 +
+
+ 171 +
+
+
    TokenStream::from(expanded)
+
+
+
+ 80 +
+
+ 171 +
+
+
}
+
+
+
+ 81 +
+
+ +
+
+

+            
+
+
+ 82 +
+
+ 40 +
+
+
fn parse_parenthesized<T: Parse>(input: ParseStream) -> Result<Vec<T>> {
+
+
+
+ 83 +
+
+ 40 +
+
+
    let content;
+
+
+
+ 84 +
+
+ 40 +
+
+
    parenthesized!(content in input);
+
+
+
+ 85 +
+
+ +
+
+

+            
+
+
+ 86 +
+
+ 40 +
+
+
    let mut paths = Vec::new();
+
+
+
+ 87 +
+
+ 42 +
+
+
    while !content.is_empty() {
+
+
+
+ 88 +
+
+ 29 +
+
+
        let path = content.parse()?;
+
+
+
+ 89 +
+
+ 29 +
+
+
        paths.push(path);
+
+
+
+ 90 +
+
+ 29 +
+
+
        if content.is_empty() {
+
+
+
+ 91 +
+
+ 27 +
+
+
            break;
+
+
+
+ 92 +
+
+ 2 +
+
+
        }
+
+
+
+ 93 +
+
+ 2 +
+
+
        content.parse::<Comma>()?;
+
+
+
+ 94 +
+
+ +
+
+
    }
+
+
+
+ 95 +
+
+ +
+
+

+            
+
+
+ 96 +
+
+ 40 +
+
+
    Ok(paths)
+
+
+
+ 97 +
+
+ 40 +
+
+
}
+
+
+
+ 98 +
+
+ +
+
+

+            
+
+
+ 99 +
+
+ +
+
+
struct RuleSetArgs {
+
+
+
+ 100 +
+
+ +
+
+
    name: LitStr,
+
+
+
+ 101 +
+
+ +
+
+
    priority: LitInt,
+
+
+
+ 102 +
+
+ +
+
+
    dependencies: Vec<LitStr>,
+
+
+
+ 103 +
+
+ +
+
+
    solver_families: Vec<Path>,
+
+
+
+ 104 +
+
+ +
+
+
}
+
+
+
+ 105 +
+
+ +
+
+

+            
+
+
+ 106 +
+
+ +
+
+
impl Parse for RuleSetArgs {
+
+
+
+ 107 +
+
+ 28 +
+
+
    fn parse(input: ParseStream) -> Result<Self> {
+
+
+
+ 108 +
+
+ 28 +
+
+
        let name = input.parse()?;
+
+
+
+ 109 +
+
+ 28 +
+
+
        input.parse::<Comma>()?;
+
+
+
+ 110 +
+
+ 28 +
+
+
        let priority = input.parse()?;
+
+
+
+ 111 +
+
+ +
+
+

+            
+
+
+ 112 +
+
+ 28 +
+
+
        if input.is_empty() {
+
+
+
+ 113 +
+
+ +
+
+
            return Ok(Self {
+
+
+
+ 114 +
+
+ +
+
+
                name,
+
+
+
+ 115 +
+
+ +
+
+
                priority,
+
+
+
+ 116 +
+
+ +
+
+
                dependencies: Vec::new(),
+
+
+
+ 117 +
+
+ +
+
+
                solver_families: Vec::new(),
+
+
+
+ 118 +
+
+ +
+
+
            });
+
+
+
+ 119 +
+
+ 28 +
+
+
        }
+
+
+
+ 120 +
+
+ 28 +
+
+

+            
+
+
+ 121 +
+
+ 28 +
+
+
        input.parse::<Comma>()?;
+
+
+
+ 122 +
+
+ 28 +
+
+
        let dependencies = parse_parenthesized::<LitStr>(input)?;
+
+
+
+ 123 +
+
+ +
+
+

+            
+
+
+ 124 +
+
+ 28 +
+
+
        if input.is_empty() {
+
+
+
+ 125 +
+
+ 16 +
+
+
            return Ok(Self {
+
+
+
+ 126 +
+
+ 16 +
+
+
                name,
+
+
+
+ 127 +
+
+ 16 +
+
+
                priority,
+
+
+
+ 128 +
+
+ 16 +
+
+
                dependencies,
+
+
+
+ 129 +
+
+ 16 +
+
+
                solver_families: Vec::new(),
+
+
+
+ 130 +
+
+ 16 +
+
+
            });
+
+
+
+ 131 +
+
+ 12 +
+
+
        }
+
+
+
+ 132 +
+
+ 12 +
+
+

+            
+
+
+ 133 +
+
+ 12 +
+
+
        input.parse::<Comma>()?;
+
+
+
+ 134 +
+
+ 12 +
+
+
        let solver_families = parse_parenthesized::<Path>(input)?;
+
+
+
+ 135 +
+
+ +
+
+

+            
+
+
+ 136 +
+
+ 12 +
+
+
        Ok(Self {
+
+
+
+ 137 +
+
+ 12 +
+
+
            name,
+
+
+
+ 138 +
+
+ 12 +
+
+
            priority,
+
+
+
+ 139 +
+
+ 12 +
+
+
            dependencies,
+
+
+
+ 140 +
+
+ 12 +
+
+
            solver_families,
+
+
+
+ 141 +
+
+ 12 +
+
+
        })
+
+
+
+ 142 +
+
+ 28 +
+
+
    }
+
+
+
+ 143 +
+
+ +
+
+
}
+
+
+
+ 144 +
+
+ +
+
+

+            
+
+
+ 145 +
+
+ +
+
+
/**
+
+
+
+ 146 +
+
+ +
+
+
* Register a rule set with the given name, priority, and dependencies.
+
+
+
+ 147 +
+
+ +
+
+
*
+
+
+
+ 148 +
+
+ 1 +
+
+
* # Example
+
+
+
+ 149 +
+
+ 1 +
+
+
* ```rust
+
+
+
+ 150 +
+
+ 1 +
+
+
 * use conjure_macros::register_rule_set;
+
+
+
+ 151 +
+
+ 1 +
+
+
 * register_rule_set!("MyRuleSet", 10, ("DependencyRuleSet", "AnotherRuleSet"));
+
+
+
+ 152 +
+
+ 1 +
+
+
* ```
+
+
+
+ 153 +
+
+ 1 +
+
+
 */
+
+
+
+ 154 +
+
+ +
+
+
#[proc_macro]
+
+
+
+ 155 +
+
+ 28 +
+
+
pub fn register_rule_set(args: TokenStream) -> TokenStream {
+
+
+
+ 156 +
+
+ +
+
+
    let RuleSetArgs {
+
+
+
+ 157 +
+
+ 28 +
+
+
        name,
+
+
+
+ 158 +
+
+ 28 +
+
+
        priority,
+
+
+
+ 159 +
+
+ 28 +
+
+
        dependencies,
+
+
+
+ 160 +
+
+ 28 +
+
+
        solver_families,
+
+
+
+ 161 +
+
+ 28 +
+
+
    } = parse_macro_input!(args as RuleSetArgs);
+
+
+
+ 162 +
+
+ +
+
+

+            
+
+
+ 163 +
+
+ 28 +
+
+
    let static_name = format!("CONJURE_GEN_RULE_SET_{}", name.value()).to_uppercase();
+
+
+
+ 164 +
+
+ 28 +
+
+
    let static_ident = Ident::new(&static_name, Span::call_site());
+
+
+
+ 165 +
+
+ +
+
+

+            
+
+
+ 166 +
+
+ 28 +
+
+
    let dependencies = quote! {
+
+
+
+ 167 +
+
+ 28 +
+
+
        #(#dependencies),*
+
+
+
+ 168 +
+
+ 28 +
+
+
    };
+
+
+
+ 169 +
+
+ +
+
+

+            
+
+
+ 170 +
+
+ 28 +
+
+
    let solver_families = quote! {
+
+
+
+ 171 +
+
+ 28 +
+
+
        #(#solver_families),*
+
+
+
+ 172 +
+
+ 28 +
+
+
    };
+
+
+
+ 173 +
+
+ +
+
+

+            
+
+
+ 174 +
+
+ 28 +
+
+
    let expanded = quote! {
+
+
+
+ 175 +
+
+ 28 +
+
+
        use ::conjure_core::rule_engine::_dependencies::*; // ToDo idk if we need to explicitly do that?
+
+
+
+ 176 +
+
+ 28 +
+
+
        #[::conjure_core::rule_engine::_dependencies::distributed_slice(::conjure_core::rule_engine::RULE_SETS_DISTRIBUTED_SLICE)]
+
+
+
+ 177 +
+
+ 28 +
+
+
        pub static #static_ident: ::conjure_core::rule_engine::RuleSet<'static> = ::conjure_core::rule_engine::RuleSet::new(#name, #priority, &[#dependencies], &[#solver_families]);
+
+
+
+ 178 +
+
+ 28 +
+
+
    };
+
+
+
+ 179 +
+
+ 28 +
+
+

+            
+
+
+ 180 +
+
+ 28 +
+
+
    TokenStream::from(expanded)
+
+
+
+ 181 +
+
+ 28 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/enum_compatability_macro/src/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/enum_compatability_macro/src/index.html new file mode 100644 index 0000000000..2be626e8e9 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/enum_compatability_macro/src/index.html @@ -0,0 +1,74 @@ + + + + + Grcov report - crates/enum_compatability_macro/src + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
lib.rs + + 100% + + + 100% + + 115 / 115 + 60%12 / 20
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/enum_compatability_macro/src/lib.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/enum_compatability_macro/src/lib.rs.html new file mode 100644 index 0000000000..cd387f67dd --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/enum_compatability_macro/src/lib.rs.html @@ -0,0 +1,3193 @@ + + + + + Grcov report - lib.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
//! A macro to document enum variants with the things that they are compatible with.
+
+
+
+ 2 +
+
+ +
+
+
//!
+
+
+
+ 3 +
+
+ +
+
+
//!
+
+
+
+ 4 +
+
+ +
+
+
//! As well as documenting each variant, this macro also generates lists of all compatible variants
+
+
+
+ 5 +
+
+ +
+
+
//! for each "thing".
+
+
+
+ 6 +
+
+ +
+
+
//!
+
+
+
+ 7 +
+
+ +
+
+
//! # Motivation
+
+
+
+ 8 +
+
+ +
+
+
//!
+
+
+
+ 9 +
+
+ +
+
+
//! This macro is used in Conjure-Oxide, a constraint modelling tool with support for multiple
+
+
+
+ 10 +
+
+ +
+
+
//! backend solvers (e.g. Minion, SAT).
+
+
+
+ 11 +
+
+ +
+
+
//!
+
+
+
+ 12 +
+
+ +
+
+
//! The Conjure-Oxide AST is used as the singular representation for constraints models throughout
+
+
+
+ 13 +
+
+ +
+
+
//! its crate. A consequence of this is that the AST must contain all possible supported
+
+
+
+ 14 +
+
+ +
+
+
//! expressions for all solvers, as well as the high level Essence language it takes as input.
+
+
+
+ 15 +
+
+ +
+
+
//! Therefore, only a small subset of AST nodes are useful for a particular solver.
+
+
+
+ 16 +
+
+ +
+
+
//!
+
+
+
+ 17 +
+
+ +
+
+
//! The documentation this generates helps rewrite rule implementers determine which AST nodes are
+
+
+
+ 18 +
+
+ +
+
+
//! used for which backends by grouping AST nodes per solver.
+
+
+
+ 19 +
+
+ +
+
+

+            
+
+
+ 20 +
+
+ +
+
+
#![allow(clippy::unwrap_used)]
+
+
+
+ 21 +
+
+ +
+
+
#![allow(unstable_name_collisions)]
+
+
+
+ 22 +
+
+ +
+
+

+            
+
+
+ 23 +
+
+ +
+
+
use proc_macro::TokenStream;
+
+
+
+ 24 +
+
+ +
+
+
use std::collections::HashMap;
+
+
+
+ 25 +
+
+ +
+
+

+            
+
+
+ 26 +
+
+ +
+
+
use itertools::Itertools;
+
+
+
+ 27 +
+
+ +
+
+
use quote::quote;
+
+
+
+ 28 +
+
+ +
+
+
use syn::{
+
+
+
+ 29 +
+
+ +
+
+
    parse_macro_input, parse_quote, punctuated::Punctuated, visit_mut::VisitMut, Attribute,
+
+
+
+ 30 +
+
+ +
+
+
    ItemEnum, Meta, Token, Variant,
+
+
+
+ 31 +
+
+ +
+
+
};
+
+
+
+ 32 +
+
+ +
+
+

+            
+
+
+ 33 +
+
+ +
+
+
// A nice S.O answer that helped write the syn code :)
+
+
+
+ 34 +
+
+ +
+
+
// https://stackoverflow.com/a/65182902
+
+
+
+ 35 +
+
+ +
+
+

+            
+
+
+ 36 +
+
+ +
+
+
struct RemoveCompatibleAttrs;
+
+
+
+ 37 +
+
+ +
+
+
impl VisitMut for RemoveCompatibleAttrs {
+
+
+
+ 38 +
+
+ 120 +
+
+
    fn visit_variant_mut(&mut self, i: &mut Variant) {
+
+
+
+ 39 +
+
+ 120 +
+
+
        // 1. generate docstring for variant
+
+
+
+ 40 +
+
+ 120 +
+
+
        // Supported by: minion, sat ...
+
+
+
+ 41 +
+
+ 120 +
+
+
        //
+
+
+
+ 42 +
+
+ 120 +
+
+
        // 2. delete #[compatible] attributes
+
+
+
+ 43 +
+
+ 120 +
+
+

+            
+
+
+ 44 +
+
+ 120 +
+
+
        let mut solvers: Vec<String> = vec![];
+
+
+
+ 45 +
+
+ 120 +
+
+
        for attr in i.attrs.iter() {
+
+
+
+ 46 +
+
+ 116 +
+
+
            if !attr.path().is_ident("compatible") {
+
+
+
+ 47 +
+
+ 6 +
+
+
                continue;
+
+
+
+ 48 +
+
+ 110 +
+
+
            }
+
+
+
+ 49 +
+
+ 110 +
+
+
            let nested = attr
+
+
+
+ 50 +
+
+ 110 +
+
+
                .parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)
+
+
+
+ 51 +
+
+ 110 +
+
+
                .unwrap();
+
+
+
+ 52 +
+
+ 263 +
+
+
            for arg in nested {
+
+
+
+ 53 +
+
+ 153 +
+
+
                let ident = arg.path().require_ident().unwrap();
+
+
+
+ 54 +
+
+ 153 +
+
+
                let solver_name = ident.to_string();
+
+
+
+ 55 +
+
+ 153 +
+
+
                solvers.push(solver_name);
+
+
+
+ 56 +
+
+ 153 +
+
+
            }
+
+
+
+ 57 +
+
+ +
+
+
        }
+
+
+
+ 58 +
+
+ +
+
+

+            
+
+
+ 59 +
+
+ 120 +
+
+
        if !solvers.is_empty() {
+
+
+
+ 60 +
+
+ 108 +
+
+
            let solver_list: String = solvers.into_iter().intersperse(", ".into()).collect();
+
+
+
+ 61 +
+
+ 108 +
+
+
            let doc_string: String = format!("**Supported by:** {}.\n", solver_list);
+
+
+
+ 62 +
+
+ 108 +
+
+
            let doc_attr: Attribute = parse_quote!(#[doc = #doc_string]);
+
+
+
+ 63 +
+
+ 108 +
+
+
            i.attrs.push(doc_attr);
+
+
+
+ 64 +
+
+ 108 +
+
+
        }
+
+
+
+ 65 +
+
+ +
+
+

+            
+
+
+ 66 +
+
+ 224 +
+
+
        i.attrs.retain(|attr| !attr.path().is_ident("compatible"));
+
+
+
+ 67 +
+
+ 120 +
+
+
    }
+
+
+
+ 68 +
+
+ +
+
+
}
+
+
+
+ 69 +
+
+ +
+
+

+            
+
+
+ 70 +
+
+ +
+
+
/// A macro to document enum variants by the things that they are compatible with.
+
+
+
+ 71 +
+
+ +
+
+
///
+
+
+
+ 72 +
+
+ +
+
+
/// # Examples
+
+
+
+ 73 +
+
+ +
+
+
///
+
+
+
+ 74 +
+
+ +
+
+
/// ```
+
+
+
+ 75 +
+
+ 1 +
+
+
/// use enum_compatability_macro::document_compatibility;
+
+
+
+ 76 +
+
+ 1 +
+
+
///
+
+
+
+ 77 +
+
+ 1 +
+
+
/// #[document_compatibility]
+
+
+
+ 78 +
+
+ 1 +
+
+
/// pub enum Expression {
+
+
+
+ 79 +
+
+ 1 +
+
+
///    #[compatible(Minion)]
+
+
+
+ 80 +
+
+ 1 +
+
+
///    ConstantInt(i32),
+
+
+
+ 81 +
+
+ 1 +
+
+
///    // ...
+
+
+
+ 82 +
+
+ 1 +
+
+
///    #[compatible(Chuffed)]
+
+
+
+ 83 +
+
+ 1 +
+
+
///    #[compatible(Minion)]
+
+
+
+ 84 +
+
+ 1 +
+
+
///    Sum(Vec<Expression>)
+
+
+
+ 85 +
+
+ 1 +
+
+
///    }
+
+
+
+ 86 +
+
+ 1 +
+
+
/// ```
+
+
+
+ 87 +
+
+ 1 +
+
+
///
+
+
+
+ 88 +
+
+ +
+
+
/// The Expression type will have the following lists appended to its documentation:
+
+
+
+ 89 +
+
+ +
+
+
///
+
+
+
+ 90 +
+
+ +
+
+
///```text
+
+
+
+ 91 +
+
+ +
+
+
/// ## Supported by `minion`
+
+
+
+ 92 +
+
+ +
+
+
///    ConstantInt(i32)
+
+
+
+ 93 +
+
+ +
+
+
///    Sum(Vec<Expression>)
+
+
+
+ 94 +
+
+ +
+
+
///
+
+
+
+ 95 +
+
+ +
+
+
///
+
+
+
+ 96 +
+
+ +
+
+
/// ## Supported by `chuffed`
+
+
+
+ 97 +
+
+ +
+
+
///    ConstantInt(i32)
+
+
+
+ 98 +
+
+ +
+
+
///    Sum(Vec<Expression>)
+
+
+
+ 99 +
+
+ +
+
+
/// ```
+
+
+
+ 100 +
+
+ +
+
+
///
+
+
+
+ 101 +
+
+ +
+
+
/// Two equivalent syntaxes exist for specifying supported solvers:
+
+
+
+ 102 +
+
+ +
+
+
///
+
+
+
+ 103 +
+
+ +
+
+
/// ```
+
+
+
+ 104 +
+
+ 1 +
+
+
///# use enum_compatability_macro::document_compatibility;
+
+
+
+ 105 +
+
+ 1 +
+
+
///#
+
+
+
+ 106 +
+
+ 1 +
+
+
///# #[document_compatibility]
+
+
+
+ 107 +
+
+ 1 +
+
+
///# pub enum Expression {
+
+
+
+ 108 +
+
+ 1 +
+
+
///#    #[compatible(Minion)]
+
+
+
+ 109 +
+
+ 1 +
+
+
///#    ConstantInt(i32),
+
+
+
+ 110 +
+
+ 1 +
+
+
///#    // ...
+
+
+
+ 111 +
+
+ 1 +
+
+
///     #[compatible(Chuffed)]
+
+
+
+ 112 +
+
+ 1 +
+
+
///     #[compatible(Minion)]
+
+
+
+ 113 +
+
+ 1 +
+
+
///     Sum(Vec<Expression>)
+
+
+
+ 114 +
+
+ 1 +
+
+
///#    }
+
+
+
+ 115 +
+
+ 1 +
+
+
/// ```
+
+
+
+ 116 +
+
+ 1 +
+
+
///
+
+
+
+ 117 +
+
+ +
+
+
/// ```
+
+
+
+ 118 +
+
+ 1 +
+
+
///# use enum_compatability_macro::document_compatibility;
+
+
+
+ 119 +
+
+ 1 +
+
+
///#
+
+
+
+ 120 +
+
+ 1 +
+
+
///# #[document_compatibility]
+
+
+
+ 121 +
+
+ 1 +
+
+
///# pub enum Expression {
+
+
+
+ 122 +
+
+ 1 +
+
+
///#    #[compatible(Minion)]
+
+
+
+ 123 +
+
+ 1 +
+
+
///#    ConstantInt(i32),
+
+
+
+ 124 +
+
+ 1 +
+
+
///#    // ...
+
+
+
+ 125 +
+
+ 1 +
+
+
///     #[compatible(Minion,Chuffed)]
+
+
+
+ 126 +
+
+ 1 +
+
+
///     Sum(Vec<Expression>)
+
+
+
+ 127 +
+
+ 1 +
+
+
///#    }
+
+
+
+ 128 +
+
+ 1 +
+
+
/// ```
+
+
+
+ 129 +
+
+ 1 +
+
+
///
+
+
+
+ 130 +
+
+ +
+
+
#[proc_macro_attribute]
+
+
+
+ 131 +
+
+ 9 +
+
+
pub fn document_compatibility(_attr: TokenStream, input: TokenStream) -> TokenStream {
+
+
+
+ 132 +
+
+ +
+
+
    // Parse the input tokens into a syntax tree
+
+
+
+ 133 +
+
+ 9 +
+
+
    let mut input = parse_macro_input!(input as ItemEnum);
+
+
+
+ 134 +
+
+ 9 +
+
+
    let mut nodes_supported_by_solver: HashMap<String, Vec<syn::Ident>> = HashMap::new();
+
+
+
+ 135 +
+
+ +
+
+

+            
+
+
+ 136 +
+
+ +
+
+
    // process each item inside the enum.
+
+
+
+ 137 +
+
+ 120 +
+
+
    for variant in input.variants.iter() {
+
+
+
+ 138 +
+
+ 120 +
+
+
        let variant_ident = variant.ident.clone();
+
+
+
+ 139 +
+
+ 120 +
+
+
        for attr in variant.attrs.iter() {
+
+
+
+ 140 +
+
+ 116 +
+
+
            if !attr.path().is_ident("compatible") {
+
+
+
+ 141 +
+
+ 6 +
+
+
                continue;
+
+
+
+ 142 +
+
+ 110 +
+
+
            }
+
+
+
+ 143 +
+
+ 110 +
+
+

+            
+
+
+ 144 +
+
+ 110 +
+
+
            let nested = attr
+
+
+
+ 145 +
+
+ 110 +
+
+
                .parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)
+
+
+
+ 146 +
+
+ 110 +
+
+
                .unwrap();
+
+
+
+ 147 +
+
+ 263 +
+
+
            for arg in nested {
+
+
+
+ 148 +
+
+ 153 +
+
+
                let ident = arg.path().require_ident().unwrap();
+
+
+
+ 149 +
+
+ 153 +
+
+
                let solver_name = ident.to_string();
+
+
+
+ 150 +
+
+ 153 +
+
+
                match nodes_supported_by_solver.get_mut(&solver_name) {
+
+
+
+ 151 +
+
+ 24 +
+
+
                    None => {
+
+
+
+ 152 +
+
+ 24 +
+
+
                        nodes_supported_by_solver.insert(solver_name, vec![variant_ident.clone()]);
+
+
+
+ 153 +
+
+ 24 +
+
+
                    }
+
+
+
+ 154 +
+
+ 129 +
+
+
                    Some(a) => {
+
+
+
+ 155 +
+
+ 129 +
+
+
                        a.push(variant_ident.clone());
+
+
+
+ 156 +
+
+ 129 +
+
+
                    }
+
+
+
+ 157 +
+
+ +
+
+
                };
+
+
+
+ 158 +
+
+ +
+
+
            }
+
+
+
+ 159 +
+
+ +
+
+
        }
+
+
+
+ 160 +
+
+ +
+
+
    }
+
+
+
+ 161 +
+
+ +
+
+

+            
+
+
+ 162 +
+
+ +
+
+
    // we must remove all references to #[compatible] before we finish expanding the macro,
+
+
+
+ 163 +
+
+ +
+
+
    // as it does not exist outside of the context of this macro.
+
+
+
+ 164 +
+
+ 9 +
+
+
    RemoveCompatibleAttrs.visit_item_enum_mut(&mut input);
+
+
+
+ 165 +
+
+ 9 +
+
+

+            
+
+
+ 166 +
+
+ 9 +
+
+
    // Build the doc string.
+
+
+
+ 167 +
+
+ 9 +
+
+

+            
+
+
+ 168 +
+
+ 9 +
+
+
    // Note that quote wants us to build the doc message first, as it cannot interpolate doc
+
+
+
+ 169 +
+
+ 9 +
+
+
    // comments well.
+
+
+
+ 170 +
+
+ 9 +
+
+
    // https://docs.rs/quote/latest/quote/macro.quote.html#interpolating-text-inside-of-doc-comments
+
+
+
+ 171 +
+
+ 9 +
+
+
    let mut doc_msg: String = "# Compatability\n".into();
+
+
+
+ 172 +
+
+ 24 +
+
+
    for solver in nodes_supported_by_solver.keys() {
+
+
+
+ 173 +
+
+ +
+
+
        // a nice title
+
+
+
+ 174 +
+
+ 24 +
+
+
        doc_msg.push_str(&format!("## {}\n", solver));
+
+
+
+ 175 +
+
+ +
+
+

+            
+
+
+ 176 +
+
+ +
+
+
        // list all the ast nodes for this solver
+
+
+
+ 177 +
+
+ 153 +
+
+
        for node in nodes_supported_by_solver
+
+
+
+ 178 +
+
+ 24 +
+
+
            .get(solver)
+
+
+
+ 179 +
+
+ 24 +
+
+
            .unwrap()
+
+
+
+ 180 +
+
+ 24 +
+
+
            .iter()
+
+
+
+ 181 +
+
+ 153 +
+
+
            .map(|x| x.to_string())
+
+
+
+ 182 +
+
+ 24 +
+
+
            .sorted()
+
+
+
+ 183 +
+
+ 153 +
+
+
        {
+
+
+
+ 184 +
+
+ 153 +
+
+
            doc_msg.push_str(&format!("* [`{}`]({}::{})\n", node, input.ident, node));
+
+
+
+ 185 +
+
+ 153 +
+
+
        }
+
+
+
+ 186 +
+
+ +
+
+

+            
+
+
+ 187 +
+
+ +
+
+
        // end list
+
+
+
+ 188 +
+
+ 24 +
+
+
        doc_msg.push('\n');
+
+
+
+ 189 +
+
+ +
+
+
    }
+
+
+
+ 190 +
+
+ +
+
+

+            
+
+
+ 191 +
+
+ 9 +
+
+
    input.attrs.push(parse_quote!(#[doc = #doc_msg]));
+
+
+
+ 192 +
+
+ 9 +
+
+
    let expanded = quote! {
+
+
+
+ 193 +
+
+ 9 +
+
+
        #input
+
+
+
+ 194 +
+
+ 9 +
+
+
    };
+
+
+
+ 195 +
+
+ 9 +
+
+

+            
+
+
+ 196 +
+
+ 9 +
+
+
    TokenStream::from(expanded)
+
+
+
+ 197 +
+
+ 9 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/biplate.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/biplate.rs.html new file mode 100644 index 0000000000..c811582ed0 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/biplate.rs.html @@ -0,0 +1,2361 @@ + + + + + Grcov report - biplate.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
//#![cfg(feature = "unstable")]
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
#![allow(clippy::type_complexity)]
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ +
+
+
use std::sync::Arc;
+
+
+
+ 6 +
+
+ +
+
+

+            
+
+
+ 7 +
+
+ +
+
+
pub use super::Tree;
+
+
+
+ 8 +
+
+ +
+
+
use im;
+
+
+
+ 9 +
+
+ +
+
+
use im::vector;
+
+
+
+ 10 +
+
+ +
+
+

+            
+
+
+ 11 +
+
+ +
+
+
pub trait Biplate<To>
+
+
+
+ 12 +
+
+ +
+
+
where
+
+
+
+ 13 +
+
+ +
+
+
    Self: Sized + Clone + Eq + Uniplate + 'static,
+
+
+
+ 14 +
+
+ +
+
+
    To: Sized + Clone + Eq + Uniplate + 'static,
+
+
+
+ 15 +
+
+ +
+
+
{
+
+
+
+ 16 +
+
+ +
+
+
    /// Returns all the top most children of type to within from.
+
+
+
+ 17 +
+
+ +
+
+
    ///
+
+
+
+ 18 +
+
+ +
+
+
    /// If from == to then this function should return the root as the single child.
+
+
+
+ 19 +
+
+ +
+
+
    fn biplate(&self) -> (Tree<To>, Box<dyn Fn(Tree<To>) -> Self>);
+
+
+
+ 20 +
+
+ +
+
+

+            
+
+
+ 21 +
+
+ +
+
+
    /// Like descend but with more general types.
+
+
+
+ 22 +
+
+ +
+
+
    ///
+
+
+
+ 23 +
+
+ +
+
+
    /// If from == to then this function does not descend. Therefore, when writing definitions it
+
+
+
+ 24 +
+
+ +
+
+
    /// is highly unlikely that this function should be used in the recursive case. A common
+
+
+
+ 25 +
+
+ +
+
+
    /// pattern is to first match the types using descendBi, then continue the recursion with
+
+
+
+ 26 +
+
+ +
+
+
    /// descend.
+
+
+
+ 27 +
+
+ +
+
+

+            
+
+
+ 28 +
+
+ +
+
+
    fn descend_bi(&self, op: Arc<dyn Fn(To) -> To>) -> Self {
+
+
+
+ 29 +
+
+ +
+
+
        let (children, ctx) = self.biplate();
+
+
+
+ 30 +
+
+ +
+
+
        ctx(children.map(op))
+
+
+
+ 31 +
+
+ +
+
+
    }
+
+
+
+ 32 +
+
+ +
+
+

+            
+
+
+ 33 +
+
+ +
+
+
    // NOTE (niklasdewally): Uniplate does something different here, and  I don't know why. In
+
+
+
+ 34 +
+
+ +
+
+
    // particular, it doesn't use structure (its version of tree.list()) at all here, and uses some
+
+
+
+ 35 +
+
+ +
+
+
    // builder thing I don't understand. My children_bi and universe_bi work though, so this might
+
+
+
+ 36 +
+
+ +
+
+
    // just be performance and Haskell related.
+
+
+
+ 37 +
+
+ +
+
+
    //
+
+
+
+ 38 +
+
+ +
+
+
    // https://github.com/ndmitchell/uniplate/blob/66a2c55a7de0f5d8b0e437479719469244e00fa4/Data/Generics/Uniplate/Internal/OperationsInc.hs#L189
+
+
+
+ 39 +
+
+ +
+
+

+            
+
+
+ 40 +
+
+ 1 +
+
+
    fn universe_bi(&self) -> im::Vector<To> {
+
+
+
+ 41 +
+
+ 1 +
+
+
        self.children_bi()
+
+
+
+ 42 +
+
+ 1 +
+
+
            .into_iter()
+
+
+
+ 43 +
+
+ 4 +
+
+
            .flat_map(|child| child.universe())
+
+
+
+ 44 +
+
+ 1 +
+
+
            .collect()
+
+
+
+ 45 +
+
+ 1 +
+
+
    }
+
+
+
+ 46 +
+
+ +
+
+

+            
+
+
+ 47 +
+
+ +
+
+
    /// Returns the children of a type. If to == from then it returns the original element (in contrast to children).
+
+
+
+ 48 +
+
+ 2 +
+
+
    fn children_bi(&self) -> im::Vector<To> {
+
+
+
+ 49 +
+
+ 2 +
+
+
        self.biplate().0.list().0
+
+
+
+ 50 +
+
+ 2 +
+
+
    }
+
+
+
+ 51 +
+
+ +
+
+

+            
+
+
+ 52 +
+
+ +
+
+
    fn transform_bi(&self, op: Arc<dyn Fn(To) -> To>) -> Self {
+
+
+
+ 53 +
+
+ +
+
+
        let (children, ctx) = self.biplate();
+
+
+
+ 54 +
+
+ +
+
+
        ctx(children.map(Arc::new(move |child| child.transform(op.clone()))))
+
+
+
+ 55 +
+
+ +
+
+
    }
+
+
+
+ 56 +
+
+ +
+
+
}
+
+
+
+ 57 +
+
+ +
+
+

+            
+
+
+ 58 +
+
+ +
+
+
pub trait Uniplate
+
+
+
+ 59 +
+
+ +
+
+
where
+
+
+
+ 60 +
+
+ +
+
+
    Self: Sized + Clone + Eq + 'static,
+
+
+
+ 61 +
+
+ +
+
+
{
+
+
+
+ 62 +
+
+ +
+
+
    fn uniplate(&self) -> (Tree<Self>, Box<dyn Fn(Tree<Self>) -> Self>);
+
+
+
+ 63 +
+
+ +
+
+

+            
+
+
+ 64 +
+
+ +
+
+
    fn descend(&self, op: Arc<dyn Fn(Self) -> Self>) -> Self {
+
+
+
+ 65 +
+
+ +
+
+
        let (children, ctx) = self.uniplate();
+
+
+
+ 66 +
+
+ +
+
+
        ctx(children.map(op))
+
+
+
+ 67 +
+
+ +
+
+
    }
+
+
+
+ 68 +
+
+ +
+
+

+            
+
+
+ 69 +
+
+ +
+
+
    /// Gest all children of a node, including itself and all children.
+
+
+
+ 70 +
+
+ 8 +
+
+
    fn universe(&self) -> im::Vector<Self> {
+
+
+
+ 71 +
+
+ 8 +
+
+
        let mut results = vector![self.clone()];
+
+
+
+ 72 +
+
+ 8 +
+
+
        for child in self.children() {
+
+
+
+ 73 +
+
+ 4 +
+
+
            results.append(child.universe());
+
+
+
+ 74 +
+
+ 4 +
+
+
        }
+
+
+
+ 75 +
+
+ 8 +
+
+
        results
+
+
+
+ 76 +
+
+ 8 +
+
+
    }
+
+
+
+ 77 +
+
+ +
+
+

+            
+
+
+ 78 +
+
+ +
+
+
    /// Gets the direct children (maximal substructures) of a node.
+
+
+
+ 79 +
+
+ 8 +
+
+
    fn children(&self) -> im::Vector<Self> {
+
+
+
+ 80 +
+
+ 8 +
+
+
        let (children, _) = self.uniplate();
+
+
+
+ 81 +
+
+ 8 +
+
+
        children.list().0.clone()
+
+
+
+ 82 +
+
+ 8 +
+
+
    }
+
+
+
+ 83 +
+
+ +
+
+

+            
+
+
+ 84 +
+
+ +
+
+
    /// Reconstructs the node with the given children.
+
+
+
+ 85 +
+
+ +
+
+
    ///
+
+
+
+ 86 +
+
+ +
+
+
    /// # Panics
+
+
+
+ 87 +
+
+ +
+
+
    ///
+
+
+
+ 88 +
+
+ +
+
+
    /// If there are a different number of children given as there were originally returned by
+
+
+
+ 89 +
+
+ +
+
+
    /// children().
+
+
+
+ 90 +
+
+ +
+
+
    fn with_children(&self, children: im::Vector<Self>) -> Self {
+
+
+
+ 91 +
+
+ +
+
+
        // 1. Turn old tree into list.
+
+
+
+ 92 +
+
+ +
+
+
        // 2. Check lists are same size.
+
+
+
+ 93 +
+
+ +
+
+
        // 3. Use the reconstruction function given by old_children.list() to
+
+
+
+ 94 +
+
+ +
+
+
        //   create a tree with the same structure but the new lists' elements .
+
+
+
+ 95 +
+
+ +
+
+

+            
+
+
+ 96 +
+
+ +
+
+
        let (old_children, ctx) = self.uniplate();
+
+
+
+ 97 +
+
+ +
+
+
        let (old_children_lst, rebuild) = old_children.list();
+
+
+
+ 98 +
+
+ +
+
+
        if old_children_lst.len() != children.len() {
+
+
+
+ 99 +
+
+ +
+
+
            panic!("with_children() given an unexpected amount of children");
+
+
+
+ 100 +
+
+ +
+
+
        } else {
+
+
+
+ 101 +
+
+ +
+
+
            ctx(rebuild(children))
+
+
+
+ 102 +
+
+ +
+
+
        }
+
+
+
+ 103 +
+
+ +
+
+
    }
+
+
+
+ 104 +
+
+ +
+
+

+            
+
+
+ 105 +
+
+ +
+
+
    /// Applies the given rule to all nodes bottom up.
+
+
+
+ 106 +
+
+ +
+
+
    fn transform(&self, f: Arc<dyn Fn(Self) -> Self>) -> Self {
+
+
+
+ 107 +
+
+ +
+
+
        let (children, ctx) = self.uniplate();
+
+
+
+ 108 +
+
+ +
+
+
        let f2 = f.clone(); // make another pointer to f for map.
+
+
+
+ 109 +
+
+ +
+
+
        f(ctx(
+
+
+
+ 110 +
+
+ +
+
+
            children.map(Arc::new(move |child| child.transform(f2.clone())))
+
+
+
+ 111 +
+
+ +
+
+
        ))
+
+
+
+ 112 +
+
+ +
+
+
    }
+
+
+
+ 113 +
+
+ +
+
+

+            
+
+
+ 114 +
+
+ +
+
+
    /// Rewrites by applying a rule everywhere it can.
+
+
+
+ 115 +
+
+ +
+
+
    fn rewrite(&self, f: Arc<dyn Fn(Self) -> Option<Self>>) -> Self {
+
+
+
+ 116 +
+
+ +
+
+
        let (children, ctx) = self.uniplate();
+
+
+
+ 117 +
+
+ +
+
+

+            
+
+
+ 118 +
+
+ +
+
+
        let f2 = f.clone(); // make another pointer to f for map.
+
+
+
+ 119 +
+
+ +
+
+
        let new_children = children.map(Arc::new(move |child| child.rewrite(f2.clone())));
+
+
+
+ 120 +
+
+ +
+
+

+            
+
+
+ 121 +
+
+ +
+
+
        match f(ctx(new_children.clone())) {
+
+
+
+ 122 +
+
+ +
+
+
            None => ctx(new_children),
+
+
+
+ 123 +
+
+ +
+
+
            Some(n) => n,
+
+
+
+ 124 +
+
+ +
+
+
        }
+
+
+
+ 125 +
+
+ +
+
+
    }
+
+
+
+ 126 +
+
+ +
+
+
    /// Performs a fold-like computation on each value.
+
+
+
+ 127 +
+
+ +
+
+
    ///
+
+
+
+ 128 +
+
+ +
+
+
    /// Working from the bottom up, this applies the given callback function to each nested
+
+
+
+ 129 +
+
+ +
+
+
    /// component.
+
+
+
+ 130 +
+
+ +
+
+
    ///
+
+
+
+ 131 +
+
+ +
+
+
    /// Unlike [`transform`](Uniplate::transform), this returns an arbitrary type, and is not
+
+
+
+ 132 +
+
+ +
+
+
    /// limited to T -> T transformations. In other words, it can transform a type into a new
+
+
+
+ 133 +
+
+ +
+
+
    /// one.
+
+
+
+ 134 +
+
+ +
+
+
    ///
+
+
+
+ 135 +
+
+ +
+
+
    /// The meaning of the callback function is the following:
+
+
+
+ 136 +
+
+ +
+
+
    ///
+
+
+
+ 137 +
+
+ +
+
+
    ///   f(element_to_fold, folded_children) -> folded_element
+
+
+
+ 138 +
+
+ +
+
+
    fn cata<T>(&self, op: Arc<dyn Fn(Self, Vec<T>) -> T>) -> T {
+
+
+
+ 139 +
+
+ +
+
+
        let children = self.children();
+
+
+
+ 140 +
+
+ +
+
+
        (*op)(
+
+
+
+ 141 +
+
+ +
+
+
            self.clone(),
+
+
+
+ 142 +
+
+ +
+
+
            children.into_iter().map(|c| c.cata(op.clone())).collect(),
+
+
+
+ 143 +
+
+ +
+
+
        )
+
+
+
+ 144 +
+
+ +
+
+
    }
+
+
+
+ 145 +
+
+ +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/index.html new file mode 100644 index 0000000000..c3862fc324 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/index.html @@ -0,0 +1,146 @@ + + + + + Grcov report - crates/uniplate/src + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
biplate.rs + + 28.99% + + + 28.99% + + 20 / 69 + 23.81%5 / 21
lib.rs + + 93.62% + + + 93.62% + + 44 / 47 + 88.89%8 / 9
tree.rs + + 96.25% + + + 96.25% + + 77 / 80 + 78.95%15 / 19
uniplate.rs + + 26.98% + + + 26.98% + + 17 / 63 + 26.32%5 / 19
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/lib.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/lib.rs.html new file mode 100644 index 0000000000..19e4577de1 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/lib.rs.html @@ -0,0 +1,1881 @@ + + + + + Grcov report - lib.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
//! A port of Haskell's [Uniplate](https://hackage.haskell.org/package/uniplate) in Rust.
+
+
+
+ 2 +
+
+ +
+
+
//!
+
+
+
+ 3 +
+
+ +
+
+
//!
+
+
+
+ 4 +
+
+ +
+
+
//! # Examples
+
+
+
+ 5 +
+
+ +
+
+
//!
+
+
+
+ 6 +
+
+ +
+
+
//! ## A Calculator Input Language
+
+
+
+ 7 +
+
+ +
+
+
//!
+
+
+
+ 8 +
+
+ +
+
+
//! Consider the AST of a calculator input language:
+
+
+
+ 9 +
+
+ +
+
+
//!
+
+
+
+ 10 +
+
+ 1 +
+
+
//! ```
+
+
+
+ 11 +
+
+ 1 +
+
+
//! pub enum AST {
+
+
+
+ 12 +
+
+ 1 +
+
+
//!     Int(i32),
+
+
+
+ 13 +
+
+ 1 +
+
+
//!     Add(Box<AST>,Box<AST>),
+
+
+
+ 14 +
+
+ 1 +
+
+
//!     Sub(Box<AST>,Box<AST>),
+
+
+
+ 15 +
+
+ 1 +
+
+
//!     Div(Box<AST>,Box<AST>),
+
+
+
+ 16 +
+
+ 1 +
+
+
//!     Mul(Box<AST>,Box<AST>)
+
+
+
+ 17 +
+
+ 1 +
+
+
//! }
+
+
+
+ 18 +
+
+ 1 +
+
+
//!```
+
+
+
+ 19 +
+
+ +
+
+
//!
+
+
+
+ 20 +
+
+ +
+
+
//! Using uniplate, one can implement a single function for this AST that can be used in a whole
+
+
+
+ 21 +
+
+ +
+
+
//! range of traversals.
+
+
+
+ 22 +
+
+ +
+
+
//!
+
+
+
+ 23 +
+
+ +
+
+
//! While this does not seem helpful in this toy example, the benefits amplify when the number of
+
+
+
+ 24 +
+
+ +
+
+
//! enum variants increase, and the different types contained in their fields increase.
+
+
+
+ 25 +
+
+ +
+
+
//!
+
+
+
+ 26 +
+
+ +
+
+
//!
+
+
+
+ 27 +
+
+ +
+
+
//! The below example implements [`Uniplate`](uniplate::Uniplate) for this language AST, and uses uniplate methods to
+
+
+
+ 28 +
+
+ +
+
+
//! evaluate the encoded equation.
+
+
+
+ 29 +
+
+ +
+
+
//!
+
+
+
+ 30 +
+
+ +
+
+
//!```
+
+
+
+ 31 +
+
+ +
+
+
//! use uniplate::uniplate::{Uniplate, UniplateError};
+
+
+
+ 32 +
+
+ +
+
+
//!
+
+
+
+ 33 +
+
+ +
+
+
//! #[derive(Clone,Eq,PartialEq,Debug)]
+
+
+
+ 34 +
+
+ +
+
+
//! pub enum AST {
+
+
+
+ 35 +
+
+ +
+
+
//!     Int(i32),
+
+
+
+ 36 +
+
+ +
+
+
//!     Add(Box<AST>,Box<AST>),
+
+
+
+ 37 +
+
+ +
+
+
//!     Sub(Box<AST>,Box<AST>),
+
+
+
+ 38 +
+
+ +
+
+
//!     Div(Box<AST>,Box<AST>),
+
+
+
+ 39 +
+
+ +
+
+
//!     Mul(Box<AST>,Box<AST>)
+
+
+
+ 40 +
+
+ +
+
+
//! }
+
+
+
+ 41 +
+
+ +
+
+
//!
+
+
+
+ 42 +
+
+ +
+
+
//! // In the future would be automatically derived.
+
+
+
+ 43 +
+
+ +
+
+
//! impl Uniplate for AST {
+
+
+
+ 44 +
+
+ +
+
+
//!     fn uniplate(&self) -> (Vec<AST>, Box<dyn Fn(Vec<AST>) -> Result<AST, UniplateError> +'_>) {
+
+
+
+ 45 +
+
+ 9 +
+
+
//!         let context: Box<dyn Fn(Vec<AST>) -> Result<AST, UniplateError>> = match self {
+
+
+
+ 46 +
+
+ 9 +
+
+
//!             AST::Int(i) =>    Box::new(|_| Ok(AST::Int(*i))),
+
+
+
+ 47 +
+
+ 5 +
+
+
//!             AST::Add(_, _) => Box::new(|exprs: Vec<AST>| Ok(AST::Add(Box::new(exprs[0].clone()),Box::new(exprs[1].clone())))),
+
+
+
+ 48 +
+
+ 2 +
+
+
//!             AST::Sub(_, _) => Box::new(|exprs: Vec<AST>| Ok(AST::Sub(Box::new(exprs[0].clone()),Box::new(exprs[1].clone())))),
+
+
+
+ 49 +
+
+ +
+
+
//!             AST::Div(_, _) => Box::new(|exprs: Vec<AST>| Ok(AST::Div(Box::new(exprs[0].clone()),Box::new(exprs[1].clone())))),
+
+
+
+ 50 +
+
+ 1 +
+
+
//!             AST::Mul(_, _) => Box::new(|exprs: Vec<AST>| Ok(AST::Mul(Box::new(exprs[0].clone()),Box::new(exprs[1].clone()))))
+
+
+
+ 51 +
+
+ 1 +
+
+
//!         };
+
+
+
+ 52 +
+
+ +
+
+
//!
+
+
+
+ 53 +
+
+ +
+
+
//!         let children: Vec<AST> = match self {
+
+
+
+ 54 +
+
+ 9 +
+
+
//!             AST::Add(a,b) => vec![*a.clone(),*b.clone()],
+
+
+
+ 55 +
+
+ 2 +
+
+
//!             AST::Sub(a,b) => vec![*a.clone(),*b.clone()],
+
+
+
+ 56 +
+
+ +
+
+
//!             AST::Div(a,b) => vec![*a.clone(),*b.clone()],
+
+
+
+ 57 +
+
+ 1 +
+
+
//!             AST::Mul(a,b) => vec![*a.clone(),*b.clone()],
+
+
+
+ 58 +
+
+ 1 +
+
+
//!             _ => vec![]
+
+
+
+ 59 +
+
+ 5 +
+
+
//!         };
+
+
+
+ 60 +
+
+ +
+
+
//!
+
+
+
+ 61 +
+
+ +
+
+
//!         (children,context)
+
+
+
+ 62 +
+
+ 9 +
+
+
//!     }
+
+
+
+ 63 +
+
+ 9 +
+
+
//! }
+
+
+
+ 64 +
+
+ +
+
+
//!
+
+
+
+ 65 +
+
+ +
+
+
//! pub fn my_rule(e: AST) -> AST{
+
+
+
+ 66 +
+
+ 9 +
+
+
//!     match e {
+
+
+
+ 67 +
+
+ 9 +
+
+
//!         AST::Int(a) => AST::Int(a),
+
+
+
+ 68 +
+
+ 5 +
+
+
//!         AST::Add(a,b) => {match (&*a,&*b) { (AST::Int(a), AST::Int(b)) => AST::Int(a+b), _ => AST::Add(a,b) }}
+
+
+
+ 69 +
+
+ 2 +
+
+
//!         AST::Sub(a,b) => {match (&*a,&*b) { (AST::Int(a), AST::Int(b)) => AST::Int(a-b), _ => AST::Sub(a,b) }}
+
+
+
+ 70 +
+
+ +
+
+
//!         AST::Mul(a,b) => {match (&*a,&*b) { (AST::Int(a), AST::Int(b)) => AST::Int(a*b), _ => AST::Mul(a,b) }}
+
+
+
+ 71 +
+
+ 1 +
+
+
//!         AST::Div(a,b) => {match (&*a,&*b) { (AST::Int(a), AST::Int(b)) => AST::Int(a/b), _ => AST::Div(a,b) }}
+
+
+
+ 72 +
+
+ 1 +
+
+
//!     }
+
+
+
+ 73 +
+
+ +
+
+
//! }
+
+
+
+ 74 +
+
+ 9 +
+
+
//! pub fn main() {
+
+
+
+ 75 +
+
+ 1 +
+
+
//!     let ast = AST::Add(
+
+
+
+ 76 +
+
+ 1 +
+
+
//!                 Box::new(AST::Int(1)),
+
+
+
+ 77 +
+
+ 1 +
+
+
//!                 Box::new(AST::Mul(
+
+
+
+ 78 +
+
+ 1 +
+
+
//!                     Box::new(AST::Int(2)),
+
+
+
+ 79 +
+
+ 1 +
+
+
//!                     Box::new(AST::Div(
+
+
+
+ 80 +
+
+ 1 +
+
+
//!                         Box::new(AST::Add(Box::new(AST::Int(1)),Box::new(AST::Int(2)))),
+
+
+
+ 81 +
+
+ 1 +
+
+
//!                         Box::new(AST::Int(3))
+
+
+
+ 82 +
+
+ 1 +
+
+
//!                     )))));
+
+
+
+ 83 +
+
+ 1 +
+
+
//!
+
+
+
+ 84 +
+
+ 1 +
+
+
//!     let new_ast = ast.transform(my_rule);
+
+
+
+ 85 +
+
+ 1 +
+
+
//!     assert!(new_ast.is_ok());
+
+
+
+ 86 +
+
+ 1 +
+
+
//!     println!("{:?}",new_ast);
+
+
+
+ 87 +
+
+ 1 +
+
+
//!     assert_eq!(new_ast.unwrap(), AST::Int(3));
+
+
+
+ 88 +
+
+ 1 +
+
+
//! }
+
+
+
+ 89 +
+
+ 1 +
+
+
//! ```
+
+
+
+ 90 +
+
+ +
+
+
//!
+
+
+
+ 91 +
+
+ +
+
+
//! ....MORE DOCS TO COME....
+
+
+
+ 92 +
+
+ +
+
+
//!
+
+
+
+ 93 +
+
+ +
+
+
//! # Acknowledgements / Related Work
+
+
+
+ 94 +
+
+ +
+
+
//!
+
+
+
+ 95 +
+
+ +
+
+
//! *This crate implements programming constructs from the following Haskell libraries and
+
+
+
+ 96 +
+
+ +
+
+
//! papers:*
+
+
+
+ 97 +
+
+ +
+
+
//!  
+
+
+
+ 98 +
+
+ +
+
+
//! * [Uniplate](https://hackage.haskell.org/package/uniplate).
+
+
+
+ 99 +
+
+ +
+
+
//!
+
+
+
+ 100 +
+
+ +
+
+
//! * Neil Mitchell and Colin Runciman. 2007. Uniform boilerplate and list processing. In
+
+
+
+ 101 +
+
+ +
+
+
//! Proceedings of the ACM SIGPLAN workshop on Haskell workshop (Haskell '07). Association for
+
+
+
+ 102 +
+
+ +
+
+
//! Computing Machinery, New York, NY, USA, 49–60. <https://doi.org/10.1145/1291201.1291208>
+
+
+
+ 103 +
+
+ +
+
+
//! [(free copy)](https://www.cs.york.ac.uk/plasma/publications/pdf/MitchellRuncimanHW07.pdf)
+
+
+
+ 104 +
+
+ +
+
+
//!
+
+
+
+ 105 +
+
+ +
+
+
//! * Huet G. The Zipper. Journal of Functional Programming. 1997;7(5):549–54. <https://doi.org/10.1017/S0956796897002864>
+
+
+
+ 106 +
+
+ +
+
+
//! [(free copy)](https://www.cambridge.org/core/services/aop-cambridge-core/content/view/0C058890B8A9B588F26E6D68CF0CE204/S0956796897002864a.pdf/zipper.pdf)
+
+
+
+ 107 +
+
+ +
+
+

+            
+
+
+ 108 +
+
+ +
+
+
pub mod biplate;
+
+
+
+ 109 +
+
+ +
+
+
mod tree;
+
+
+
+ 110 +
+
+ +
+
+
pub mod uniplate;
+
+
+
+ 111 +
+
+ +
+
+

+            
+
+
+ 112 +
+
+ +
+
+
pub use tree::Tree;
+
+
+
+ 113 +
+
+ +
+
+

+            
+
+
+ 114 +
+
+ +
+
+
#[doc(hidden)]
+
+
+
+ 115 +
+
+ +
+
+
pub mod test_common;
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/test_common/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/test_common/index.html new file mode 100644 index 0000000000..f44e5fa646 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/test_common/index.html @@ -0,0 +1,74 @@ + + + + + Grcov report - crates/uniplate/src/test_common + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
paper.rs + + 0% + + + 0% + + 0 / 35 + 0%0 / 12
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/test_common/paper.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/test_common/paper.rs.html new file mode 100644 index 0000000000..6558cc767d --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/test_common/paper.rs.html @@ -0,0 +1,1033 @@ + + + + + Grcov report - paper.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use proptest::prelude::*;
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
// Examples found in the Uniplate paper.
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ +
+
+
// Stmt and Expr to demonstrate and test multitype traversals.
+
+
+
+ 6 +
+
+ +
+
+
#[derive(Eq, PartialEq, Clone, Debug)]
+
+
+
+ 7 +
+
+ +
+
+
pub enum Stmt {
+
+
+
+ 8 +
+
+ +
+
+
    Assign(String, Expr),
+
+
+
+ 9 +
+
+ +
+
+
    Sequence(Vec<Stmt>),
+
+
+
+ 10 +
+
+ +
+
+
    If(Expr, Box<Stmt>, Box<Stmt>),
+
+
+
+ 11 +
+
+ +
+
+
    While(Expr, Box<Stmt>),
+
+
+
+ 12 +
+
+ +
+
+
}
+
+
+
+ 13 +
+
+ +
+
+

+            
+
+
+ 14 +
+
+ +
+
+
#[derive(Eq, PartialEq, Clone, Debug)]
+
+
+
+ 15 +
+
+ +
+
+
pub enum Expr {
+
+
+
+ 16 +
+
+ +
+
+
    Add(Box<Expr>, Box<Expr>),
+
+
+
+ 17 +
+
+ +
+
+
    Sub(Box<Expr>, Box<Expr>),
+
+
+
+ 18 +
+
+ +
+
+
    Mul(Box<Expr>, Box<Expr>),
+
+
+
+ 19 +
+
+ +
+
+
    Div(Box<Expr>, Box<Expr>),
+
+
+
+ 20 +
+
+ +
+
+
    Val(i32),
+
+
+
+ 21 +
+
+ +
+
+
    Var(String),
+
+
+
+ 22 +
+
+ +
+
+
    Neg(Box<Expr>),
+
+
+
+ 23 +
+
+ +
+
+
}
+
+
+
+ 24 +
+
+ +
+
+

+            
+
+
+ 25 +
+
+ +
+
+
use self::Expr::*;
+
+
+
+ 26 +
+
+ +
+
+
use self::Stmt::*;
+
+
+
+ 27 +
+
+ +
+
+
pub fn proptest_exprs() -> impl Strategy<Value = Expr> {
+
+
+
+ 28 +
+
+ +
+
+
    let leafs = prop_oneof![any::<i32>().prop_map(Val), any::<String>().prop_map(Var),];
+
+
+
+ 29 +
+
+ +
+
+

+            
+
+
+ 30 +
+
+ +
+
+
    leafs.prop_recursive(10, 512, 2, |inner| {
+
+
+
+ 31 +
+
+ +
+
+
        prop_oneof![
+
+
+
+ 32 +
+
+ +
+
+
            prop::collection::vec(inner.clone(), 2..2)
+
+
+
+ 33 +
+
+ +
+
+
                .prop_map(|elems| Add(Box::new(elems[0].clone()), Box::new(elems[1].clone()))),
+
+
+
+ 34 +
+
+ +
+
+
            prop::collection::vec(inner.clone(), 2..2)
+
+
+
+ 35 +
+
+ +
+
+
                .prop_map(|elems| Sub(Box::new(elems[0].clone()), Box::new(elems[1].clone()))),
+
+
+
+ 36 +
+
+ +
+
+
            prop::collection::vec(inner.clone(), 2..2)
+
+
+
+ 37 +
+
+ +
+
+
                .prop_map(|elems| Mul(Box::new(elems[0].clone()), Box::new(elems[1].clone()))),
+
+
+
+ 38 +
+
+ +
+
+
            prop::collection::vec(inner.clone(), 2..2)
+
+
+
+ 39 +
+
+ +
+
+
                .prop_map(|elems| Div(Box::new(elems[0].clone()), Box::new(elems[1].clone()))),
+
+
+
+ 40 +
+
+ +
+
+
            inner.prop_map(|inner| Neg(Box::new(inner.clone())))
+
+
+
+ 41 +
+
+ +
+
+
        ]
+
+
+
+ 42 +
+
+ +
+
+
    })
+
+
+
+ 43 +
+
+ +
+
+
}
+
+
+
+ 44 +
+
+ +
+
+

+            
+
+
+ 45 +
+
+ +
+
+
pub fn proptest_stmts() -> impl Strategy<Value = Stmt> {
+
+
+
+ 46 +
+
+ +
+
+
    let leafs = prop_oneof![(".*", proptest_exprs()).prop_map(|(a, b)| Assign(a, b)),];
+
+
+
+ 47 +
+
+ +
+
+

+            
+
+
+ 48 +
+
+ +
+
+
    leafs.prop_recursive(10, 512, 50, |inner| {
+
+
+
+ 49 +
+
+ +
+
+
        prop_oneof![
+
+
+
+ 50 +
+
+ +
+
+
            (proptest_exprs(), prop::collection::vec(inner.clone(), 2..2)).prop_map(
+
+
+
+ 51 +
+
+ +
+
+
                move |(expr, stmts)| If(
+
+
+
+ 52 +
+
+ +
+
+
                    expr,
+
+
+
+ 53 +
+
+ +
+
+
                    Box::new(stmts[0].clone()),
+
+
+
+ 54 +
+
+ +
+
+
                    Box::new(stmts[1].clone())
+
+
+
+ 55 +
+
+ +
+
+
                )
+
+
+
+ 56 +
+
+ +
+
+
            ),
+
+
+
+ 57 +
+
+ +
+
+
            (proptest_exprs(), inner.clone())
+
+
+
+ 58 +
+
+ +
+
+
                .prop_map(move |(expr, stmt)| While(expr, Box::new(stmt))),
+
+
+
+ 59 +
+
+ +
+
+
            prop::collection::vec(inner.clone(), 0..50).prop_map(Sequence)
+
+
+
+ 60 +
+
+ +
+
+
        ]
+
+
+
+ 61 +
+
+ +
+
+
    })
+
+
+
+ 62 +
+
+ +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/tree.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/tree.rs.html new file mode 100644 index 0000000000..d40bb89b97 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/tree.rs.html @@ -0,0 +1,2409 @@ + + + + + Grcov report - tree.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
//#![cfg(feature = "unstable")]
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
use std::sync::Arc;
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ +
+
+
use im::vector;
+
+
+
+ 6 +
+
+ +
+
+
use proptest::prelude::*;
+
+
+
+ 7 +
+
+ +
+
+

+            
+
+
+ 8 +
+
+ +
+
+
use self::Tree::*;
+
+
+
+ 9 +
+
+ +
+
+

+            
+
+
+ 10 +
+
+ +
+
+
#[derive(Clone, Debug, Eq, PartialEq)]
+
+
+
+ 11 +
+
+ +
+
+
pub enum Tree<T: Sized + Clone + Eq> {
+
+
+
+ 12 +
+
+ +
+
+
    Zero,
+
+
+
+ 13 +
+
+ +
+
+
    One(T),
+
+
+
+ 14 +
+
+ +
+
+
    Many(im::Vector<Tree<T>>),
+
+
+
+ 15 +
+
+ +
+
+
}
+
+
+
+ 16 +
+
+ +
+
+

+            
+
+
+ 17 +
+
+ +
+
+
// NOTE (niklasdewally): This converts the entire tree into a list. Therefore this is only really
+
+
+
+ 18 +
+
+ +
+
+
// worth it when we use all the children returned. This is what we use this for inside Uniplate.
+
+
+
+ 19 +
+
+ +
+
+
// Because of this, I think a .iter() / IntoIterator for Tree<&T> is a bad idea.
+
+
+
+ 20 +
+
+ +
+
+

+            
+
+
+ 21 +
+
+ +
+
+
impl<T: Sized + Clone + Eq + 'static> IntoIterator for Tree<T> {
+
+
+
+ 22 +
+
+ +
+
+
    type Item = T;
+
+
+
+ 23 +
+
+ +
+
+

+            
+
+
+ 24 +
+
+ +
+
+
    type IntoIter = im::vector::ConsumingIter<T>;
+
+
+
+ 25 +
+
+ +
+
+

+            
+
+
+ 26 +
+
+ +
+
+
    fn into_iter(self) -> Self::IntoIter {
+
+
+
+ 27 +
+
+ +
+
+
        self.list().0.into_iter()
+
+
+
+ 28 +
+
+ +
+
+
    }
+
+
+
+ 29 +
+
+ +
+
+
}
+
+
+
+ 30 +
+
+ +
+
+
impl<T: Sized + Clone + Eq + 'static> Tree<T> {
+
+
+
+ 31 +
+
+ +
+
+
    /// Returns the tree as a list alongside a function to reconstruct the tree from a list.
+
+
+
+ 32 +
+
+ +
+
+
    ///
+
+
+
+ 33 +
+
+ +
+
+
    /// This preserves the structure of the tree.
+
+
+
+ 34 +
+
+ +
+
+
    #[allow(clippy::type_complexity)]
+
+
+
+ 35 +
+
+ 785 +
+
+
    pub fn list(self) -> (im::Vector<T>, Box<dyn Fn(im::Vector<T>) -> Tree<T>>) {
+
+
+
+ 36 +
+
+ 785 +
+
+
        // inspired by the Uniplate Haskell equivalent Data.Generics.Str::strStructure
+
+
+
+ 37 +
+
+ 785 +
+
+
        // https://github.com/ndmitchell/uniplate/blob/master/Data/Generics/Str.hs#L85
+
+
+
+ 38 +
+
+ 785 +
+
+

+            
+
+
+ 39 +
+
+ 28415 +
+
+
        fn flatten<T: Sized + Clone + Eq>(t: Tree<T>, xs: im::Vector<T>) -> im::Vector<T> {
+
+
+
+ 40 +
+
+ 28415 +
+
+
            match (t, xs) {
+
+
+
+ 41 +
+
+ 12883 +
+
+
                (Zero, xs) => xs,
+
+
+
+ 42 +
+
+ 12581 +
+
+
                (One(x), xs) => {
+
+
+
+ 43 +
+
+ 12581 +
+
+
                    let mut xs1 = xs.clone();
+
+
+
+ 44 +
+
+ 12581 +
+
+
                    xs1.push_back(x);
+
+
+
+ 45 +
+
+ 12581 +
+
+
                    xs1
+
+
+
+ 46 +
+
+ 785 +
+
+
                }
+
+
+
+ 47 +
+
+ 27630 +
+
+
                (Many(ts), xs) => ts.into_iter().fold(xs, |xs, t| flatten(t, xs)),
+
+
+
+ 48 +
+
+ 785 +
+
+
            }
+
+
+
+ 49 +
+
+ 28415 +
+
+
        }
+
+
+
+ 50 +
+
+ 785 +
+
+

+            
+
+
+ 51 +
+
+ 785 +
+
+
        // Iterate over both the old tree and the new list.
+
+
+
+ 52 +
+
+ 785 +
+
+
        // We use the node types of the old tree to know what node types to use for the new tree.
+
+
+
+ 53 +
+
+ 10033 +
+
+
        fn recons<T: Sized + Clone + Eq>(
+
+
+
+ 54 +
+
+ 10023 +
+
+
            old_tree: Tree<T>,
+
+
+
+ 55 +
+
+ 10023 +
+
+
            xs: im::Vector<T>,
+
+
+
+ 56 +
+
+ 10023 +
+
+
        ) -> (Tree<T>, im::Vector<T>) {
+
+
+
+ 57 +
+
+ 10023 +
+
+
            #[allow(clippy::unwrap_used)]
+
+
+
+ 58 +
+
+ 10023 +
+
+
            match (old_tree, xs) {
+
+
+
+ 59 +
+
+ 4586 +
+
+
                (Zero, xs) => (Zero, xs),
+
+
+
+ 60 +
+
+ 4436 +
+
+
                (One(_), xs) => {
+
+
+
+ 61 +
+
+ 4426 +
+
+
                    let mut xs1 = xs.clone();
+
+
+
+ 62 +
+
+ 4426 +
+
+
                    (One(xs1.pop_front().unwrap()), xs1)
+
+
+
+ 63 +
+
+ 785 +
+
+
                }
+
+
+
+ 64 +
+
+ 1031 +
+
+
                (Many(ts), xs) => {
+
+
+
+ 65 +
+
+ 9765 +
+
+
                    let (ts1, xs1) = ts.into_iter().fold((vector![], xs), |(ts1, xs), t| {
+
+
+
+ 66 +
+
+ 9765 +
+
+
                        let (t1, xs1) = recons(t, xs);
+
+
+
+ 67 +
+
+ 9765 +
+
+
                        let mut ts2 = ts1.clone();
+
+
+
+ 68 +
+
+ 9765 +
+
+
                        ts2.push_back(t1);
+
+
+
+ 69 +
+
+ 9765 +
+
+
                        (ts2, xs1)
+
+
+
+ 70 +
+
+ 9765 +
+
+
                    });
+
+
+
+ 71 +
+
+ 1021 +
+
+
                    (Many(ts1), xs1)
+
+
+
+ 72 +
+
+ 785 +
+
+
                }
+
+
+
+ 73 +
+
+ 785 +
+
+
            }
+
+
+
+ 74 +
+
+ 10033 +
+
+
        }
+
+
+
+ 75 +
+
+ 785 +
+
+
        (
+
+
+
+ 76 +
+
+ 785 +
+
+
            flatten(self.clone(), vector![]),
+
+
+
+ 77 +
+
+ 785 +
+
+
            Box::new(move |xs| recons(self.clone(), xs).0),
+
+
+
+ 78 +
+
+ 785 +
+
+
        )
+
+
+
+ 79 +
+
+ 785 +
+
+
    }
+
+
+
+ 80 +
+
+ +
+
+

+            
+
+
+ 81 +
+
+ +
+
+
    // Perform a map over all elements in the tree.
+
+
+
+ 82 +
+
+ 9170 +
+
+
    pub fn map(self, op: Arc<dyn Fn(T) -> T>) -> Tree<T> {
+
+
+
+ 83 +
+
+ 9170 +
+
+
        match self {
+
+
+
+ 84 +
+
+ 4147 +
+
+
            Zero => Zero,
+
+
+
+ 85 +
+
+ 4069 +
+
+
            One(t) => One(op(t)),
+
+
+
+ 86 +
+
+ 8912 +
+
+
            Many(ts) => Many(ts.into_iter().map(|t| t.map(op.clone())).collect()),
+
+
+
+ 87 +
+
+ +
+
+
        }
+
+
+
+ 88 +
+
+ 9170 +
+
+
    }
+
+
+
+ 89 +
+
+ +
+
+
}
+
+
+
+ 90 +
+
+ +
+
+

+            
+
+
+ 91 +
+
+ +
+
+
#[allow(dead_code)]
+
+
+
+ 92 +
+
+ +
+
+
// Used by proptest for generating test instances of Tree<i32>.
+
+
+
+ 93 +
+
+ 2 +
+
+
fn proptest_integer_trees() -> impl Strategy<Value = Tree<i32>> {
+
+
+
+ 94 +
+
+ 2 +
+
+
    // https://proptest-rs.github.io/proptest/proptest/tutorial/enums.html
+
+
+
+ 95 +
+
+ 2 +
+
+
    // https://proptest-rs.github.io/proptest/proptest/tutorial/recursive.html
+
+
+
+ 96 +
+
+ 2 +
+
+
    let leaf = prop_oneof![Just(Tree::Zero), any::<i32>().prop_map(Tree::One),];
+
+
+
+ 97 +
+
+ 2 +
+
+

+            
+
+
+ 98 +
+
+ 2 +
+
+
    leaf.prop_recursive(
+
+
+
+ 99 +
+
+ 2 +
+
+
        10,  // levels deep
+
+
+
+ 100 +
+
+ 2 +
+
+
        512, // Shoot for maximum size of 512 nodes
+
+
+
+ 101 +
+
+ 2 +
+
+
        20,  // We put up to 20 items per collection
+
+
+
+ 102 +
+
+ 5160 +
+
+
        |inner| im::proptest::vector(inner.clone(), 0..20).prop_map(Tree::Many),
+
+
+
+ 103 +
+
+ 2 +
+
+
    )
+
+
+
+ 104 +
+
+ 2 +
+
+
}
+
+
+
+ 105 +
+
+ +
+
+

+            
+
+
+ 106 +
+
+ +
+
+
#[cfg(test)]
+
+
+
+ 107 +
+
+ +
+
+
mod tests {
+
+
+
+ 108 +
+
+ +
+
+
    use std::iter::zip;
+
+
+
+ 109 +
+
+ +
+
+

+            
+
+
+ 110 +
+
+ +
+
+
    use super::*;
+
+
+
+ 111 +
+
+ +
+
+

+            
+
+
+ 112 +
+
+ +
+
+
    proptest! {
+
+
+
+ 113 +
+
+ +
+
+
        #[test]
+
+
+
+ 114 +
+
+ +
+
+
        // Is tree.recons() isomorphic?
+
+
+
+ 115 +
+
+ +
+
+
        fn list_is_isomorphic(tree in proptest_integer_trees()) {
+
+
+
+ 116 +
+
+ +
+
+
            let (children,func) = tree.clone().list();
+
+
+
+ 117 +
+
+ +
+
+
            let new_tree = func(children);
+
+
+
+ 118 +
+
+ +
+
+
            prop_assert_eq!(new_tree,tree);
+
+
+
+ 119 +
+
+ +
+
+
        }
+
+
+
+ 120 +
+
+ +
+
+

+            
+
+
+ 121 +
+
+ +
+
+
        #[test]
+
+
+
+ 122 +
+
+ +
+
+
        fn map_add(tree in proptest_integer_trees(), diff in -100i32..100i32) {
+
+
+
+ 123 +
+
+ 4069 +
+
+
            let new_tree = tree.clone().map(Arc::new(move |a| a+diff));
+
+
+
+ 124 +
+
+ +
+
+
            let (old_children,_) = tree.list();
+
+
+
+ 125 +
+
+ +
+
+
            let (new_children,_) = new_tree.list();
+
+
+
+ 126 +
+
+ +
+
+

+            
+
+
+ 127 +
+
+ +
+
+
            for (old,new) in zip(old_children,new_children) {
+
+
+
+ 128 +
+
+ +
+
+
                prop_assert_eq!(old+diff,new);
+
+
+
+ 129 +
+
+ +
+
+
            }
+
+
+
+ 130 +
+
+ +
+
+
        }
+
+
+
+ 131 +
+
+ +
+
+
    }
+
+
+
+ 132 +
+
+ +
+
+
    #[test]
+
+
+
+ 133 +
+
+ 1 +
+
+
    fn list_preserves_ordering() {
+
+
+
+ 134 +
+
+ 1 +
+
+
        let my_tree: Tree<i32> = Many(vector![
+
+
+
+ 135 +
+
+ 1 +
+
+
            Many(vector![One(0), Zero]),
+
+
+
+ 136 +
+
+ 1 +
+
+
            Many(vector![Many(vector![Zero, One(1), One(2)])]),
+
+
+
+ 137 +
+
+ 1 +
+
+
            One(3),
+
+
+
+ 138 +
+
+ 1 +
+
+
            Zero,
+
+
+
+ 139 +
+
+ 1 +
+
+
            One(4)
+
+
+
+ 140 +
+
+ 1 +
+
+
        ]);
+
+
+
+ 141 +
+
+ 1 +
+
+

+            
+
+
+ 142 +
+
+ 1 +
+
+
        let flat = my_tree.list().0;
+
+
+
+ 143 +
+
+ +
+
+

+            
+
+
+ 144 +
+
+ 6 +
+
+
        for i in 0..5 {
+
+
+
+ 145 +
+
+ 5 +
+
+
            assert_eq!(flat[i], i.try_into().unwrap());
+
+
+
+ 146 +
+
+ +
+
+
        }
+
+
+
+ 147 +
+
+ 1 +
+
+
    }
+
+
+
+ 148 +
+
+ +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/uniplate.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/uniplate.rs.html new file mode 100644 index 0000000000..c8ec9e3bf4 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/src/uniplate.rs.html @@ -0,0 +1,2409 @@ + + + + + Grcov report - uniplate.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use thiserror::Error;
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
#[derive(Debug, PartialEq, Eq, Error)]
+
+
+
+ 4 +
+
+ +
+
+
pub enum UniplateError {
+
+
+
+ 5 +
+
+ +
+
+
    #[error("Could not reconstruct node because wrong number of children was provided. Expected {0} children, got {1}.")]
+
+
+
+ 6 +
+
+ +
+
+
    WrongNumberOfChildren(usize, usize),
+
+
+
+ 7 +
+
+ +
+
+
}
+
+
+
+ 8 +
+
+ +
+
+

+            
+
+
+ 9 +
+
+ +
+
+
pub trait Uniplate
+
+
+
+ 10 +
+
+ +
+
+
where
+
+
+
+ 11 +
+
+ +
+
+
    Self: Sized + Clone + Eq,
+
+
+
+ 12 +
+
+ +
+
+
{
+
+
+
+ 13 +
+
+ +
+
+
    /// The `uniplate` function. Takes a node and produces a tuple of `(children, context)`, where:
+
+
+
+ 14 +
+
+ +
+
+
    /// - children is a list of the node's direct descendants of the same type
+
+
+
+ 15 +
+
+ +
+
+
    /// - context is a function to reconstruct the original node with a new list of children
+
+
+
+ 16 +
+
+ +
+
+
    ///
+
+
+
+ 17 +
+
+ +
+
+
    /// ## Warning
+
+
+
+ 18 +
+
+ +
+
+
    ///
+
+
+
+ 19 +
+
+ +
+
+
    /// The number of children passed to context must be the same as the number of children in
+
+
+
+ 20 +
+
+ +
+
+
    /// the original node.
+
+
+
+ 21 +
+
+ +
+
+
    /// If the number of children given is different, context returns `UniplateError::NotEnoughChildren`
+
+
+
+ 22 +
+
+ +
+
+
    #[allow(clippy::type_complexity)]
+
+
+
+ 23 +
+
+ +
+
+
    fn uniplate(
+
+
+
+ 24 +
+
+ +
+
+
        &self,
+
+
+
+ 25 +
+
+ +
+
+
    ) -> (
+
+
+
+ 26 +
+
+ +
+
+
        Vec<Self>,
+
+
+
+ 27 +
+
+ +
+
+
        Box<dyn Fn(Vec<Self>) -> Result<Self, UniplateError> + '_>,
+
+
+
+ 28 +
+
+ +
+
+
    );
+
+
+
+ 29 +
+
+ +
+
+

+            
+
+
+ 30 +
+
+ +
+
+
    /// Get all children of a node, including itself and all children.
+
+
+
+ 31 +
+
+ +
+
+
    fn universe(&self) -> Vec<Self> {
+
+
+
+ 32 +
+
+ +
+
+
        let mut results = vec![self.clone()];
+
+
+
+ 33 +
+
+ +
+
+
        for child in self.children() {
+
+
+
+ 34 +
+
+ +
+
+
            results.append(&mut child.universe());
+
+
+
+ 35 +
+
+ +
+
+
        }
+
+
+
+ 36 +
+
+ +
+
+
        results
+
+
+
+ 37 +
+
+ +
+
+
    }
+
+
+
+ 38 +
+
+ +
+
+

+            
+
+
+ 39 +
+
+ +
+
+
    /// Get the DIRECT children of a node.
+
+
+
+ 40 +
+
+ 70395 +
+
+
    fn children(&self) -> Vec<Self> {
+
+
+
+ 41 +
+
+ 70395 +
+
+
        self.uniplate().0
+
+
+
+ 42 +
+
+ 70395 +
+
+
    }
+
+
+
+ 43 +
+
+ +
+
+

+            
+
+
+ 44 +
+
+ +
+
+
    /// Reconstruct this node with the given children
+
+
+
+ 45 +
+
+ +
+
+
    ///
+
+
+
+ 46 +
+
+ +
+
+
    /// ## Arguments
+
+
+
+ 47 +
+
+ +
+
+
    /// - children - a vector of the same type and same size as self.children()
+
+
+
+ 48 +
+
+ 1770 +
+
+
    fn with_children(&self, children: Vec<Self>) -> Result<Self, UniplateError> {
+
+
+
+ 49 +
+
+ 1770 +
+
+
        let context = self.uniplate().1;
+
+
+
+ 50 +
+
+ 1770 +
+
+
        context(children)
+
+
+
+ 51 +
+
+ 1770 +
+
+
    }
+
+
+
+ 52 +
+
+ +
+
+

+            
+
+
+ 53 +
+
+ +
+
+
    /// Apply the given rule to all nodes bottom up.
+
+
+
+ 54 +
+
+ 9 +
+
+
    fn transform(&self, f: fn(Self) -> Self) -> Result<Self, UniplateError> {
+
+
+
+ 55 +
+
+ 9 +
+
+
        let (children, context) = self.uniplate();
+
+
+
+ 56 +
+
+ 9 +
+
+

+            
+
+
+ 57 +
+
+ 9 +
+
+
        let mut new_children: Vec<Self> = Vec::new();
+
+
+
+ 58 +
+
+ 17 +
+
+
        for ch in children {
+
+
+
+ 59 +
+
+ 8 +
+
+
            let new_ch = ch.transform(f)?;
+
+
+
+ 60 +
+
+ 8 +
+
+
            new_children.push(new_ch);
+
+
+
+ 61 +
+
+ +
+
+
        }
+
+
+
+ 62 +
+
+ +
+
+

+            
+
+
+ 63 +
+
+ 9 +
+
+
        let transformed = context(new_children)?;
+
+
+
+ 64 +
+
+ 9 +
+
+
        Ok(f(transformed))
+
+
+
+ 65 +
+
+ 9 +
+
+
    }
+
+
+
+ 66 +
+
+ +
+
+

+            
+
+
+ 67 +
+
+ +
+
+
    /// Rewrite by applying a rule everywhere you can.
+
+
+
+ 68 +
+
+ +
+
+
    fn rewrite(&self, f: fn(Self) -> Option<Self>) -> Result<Self, UniplateError> {
+
+
+
+ 69 +
+
+ +
+
+
        let (children, context) = self.uniplate();
+
+
+
+ 70 +
+
+ +
+
+

+            
+
+
+ 71 +
+
+ +
+
+
        let mut new_children: Vec<Self> = Vec::new();
+
+
+
+ 72 +
+
+ +
+
+
        for ch in children {
+
+
+
+ 73 +
+
+ +
+
+
            let new_ch = ch.rewrite(f)?;
+
+
+
+ 74 +
+
+ +
+
+
            new_children.push(new_ch);
+
+
+
+ 75 +
+
+ +
+
+
        }
+
+
+
+ 76 +
+
+ +
+
+

+            
+
+
+ 77 +
+
+ +
+
+
        let node: Self = context(new_children)?;
+
+
+
+ 78 +
+
+ +
+
+
        Ok(f(node.clone()).unwrap_or(node))
+
+
+
+ 79 +
+
+ +
+
+
    }
+
+
+
+ 80 +
+
+ +
+
+

+            
+
+
+ 81 +
+
+ +
+
+
    /// Perform a transformation on all the immediate children, then combine them back.
+
+
+
+ 82 +
+
+ +
+
+
    /// This operation allows additional information to be passed downwards, and can be used to provide a top-down transformation.
+
+
+
+ 83 +
+
+ +
+
+
    fn descend(&self, f: fn(Self) -> Self) -> Result<Self, UniplateError> {
+
+
+
+ 84 +
+
+ +
+
+
        let (children, context) = self.uniplate();
+
+
+
+ 85 +
+
+ +
+
+
        let children: Vec<Self> = children.into_iter().map(f).collect();
+
+
+
+ 86 +
+
+ +
+
+

+            
+
+
+ 87 +
+
+ +
+
+
        context(children)
+
+
+
+ 88 +
+
+ +
+
+
    }
+
+
+
+ 89 +
+
+ +
+
+

+            
+
+
+ 90 +
+
+ +
+
+
    /// Perform a fold-like computation on each value.
+
+
+
+ 91 +
+
+ +
+
+
    ///
+
+
+
+ 92 +
+
+ +
+
+
    /// Working from the bottom up, this applies the given callback function to each nested
+
+
+
+ 93 +
+
+ +
+
+
    /// component.
+
+
+
+ 94 +
+
+ +
+
+
    ///
+
+
+
+ 95 +
+
+ +
+
+
    /// Unlike [`transform`](Uniplate::transform), this returns an arbitrary type, and is not
+
+
+
+ 96 +
+
+ +
+
+
    /// limited to T -> T transformations. In other words, it can transform a type into a new
+
+
+
+ 97 +
+
+ +
+
+
    /// one.
+
+
+
+ 98 +
+
+ +
+
+
    ///
+
+
+
+ 99 +
+
+ +
+
+
    /// The meaning of the callback function is the following:
+
+
+
+ 100 +
+
+ +
+
+
    ///
+
+
+
+ 101 +
+
+ +
+
+
    ///   f(element_to_fold, folded_children) -> folded_element
+
+
+
+ 102 +
+
+ +
+
+
    ///
+
+
+
+ 103 +
+
+ +
+
+
    fn fold<T>(&self, op: fn(Self, Vec<T>) -> T) -> T {
+
+
+
+ 104 +
+
+ +
+
+
        op(
+
+
+
+ 105 +
+
+ +
+
+
            self.clone(),
+
+
+
+ 106 +
+
+ +
+
+
            self.children().into_iter().map(|c| c.fold(op)).collect(),
+
+
+
+ 107 +
+
+ +
+
+
        )
+
+
+
+ 108 +
+
+ +
+
+
    }
+
+
+
+ 109 +
+
+ +
+
+

+            
+
+
+ 110 +
+
+ +
+
+
    /// Get the nth one holed context.
+
+
+
+ 111 +
+
+ +
+
+
    ///
+
+
+
+ 112 +
+
+ +
+
+
    /// A uniplate context for type T has holes where all the nested T's should be.
+
+
+
+ 113 +
+
+ +
+
+
    /// This is encoded as a function Vec<T> -> T.
+
+
+
+ 114 +
+
+ +
+
+
    ///
+
+
+
+ 115 +
+
+ +
+
+
    /// On the other hand, the nth one-holed context has only one hole where the nth nested
+
+
+
+ 116 +
+
+ +
+
+
    /// instance of T would be.
+
+
+
+ 117 +
+
+ +
+
+
    ///
+
+
+
+ 118 +
+
+ +
+
+
    /// Eg. for some type:
+
+
+
+ 119 +
+
+ +
+
+
    /// ```ignore
+
+
+
+ 120 +
+
+ +
+
+
    /// enum Expr {
+
+
+
+ 121 +
+
+ +
+
+
    ///     F(A,Expr,A,Expr,A),
+
+
+
+ 122 +
+
+ +
+
+
    ///     G(Expr,A,A)
+
+
+
+ 123 +
+
+ +
+
+
    /// }
+
+
+
+ 124 +
+
+ +
+
+
    /// ```
+
+
+
+ 125 +
+
+ +
+
+
    ///
+
+
+
+ 126 +
+
+ +
+
+
    /// The 1st one-holed context of `F` (using 0-indexing) would be:
+
+
+
+ 127 +
+
+ +
+
+
    /// ```ignore
+
+
+
+ 128 +
+
+ +
+
+
    /// |HOLE| F(a,b,c,HOLE,e)
+
+
+
+ 129 +
+
+ +
+
+
    /// ```
+
+
+
+ 130 +
+
+ +
+
+
    ///
+
+
+
+ 131 +
+
+ +
+
+
    /// Used primarily in the implementation of Zippers.
+
+
+
+ 132 +
+
+ +
+
+
    fn one_holed_context(&self, n: usize) -> Option<Box<dyn Fn(Self) -> Self + '_>> {
+
+
+
+ 133 +
+
+ +
+
+
        let (children, context) = self.uniplate();
+
+
+
+ 134 +
+
+ +
+
+
        let number_of_elems = children.len();
+
+
+
+ 135 +
+
+ +
+
+

+            
+
+
+ 136 +
+
+ +
+
+
        if n >= number_of_elems {
+
+
+
+ 137 +
+
+ +
+
+
            return None;
+
+
+
+ 138 +
+
+ +
+
+
        }
+
+
+
+ 139 +
+
+ +
+
+

+            
+
+
+ 140 +
+
+ +
+
+
        Some(Box::new(move |x| {
+
+
+
+ 141 +
+
+ +
+
+
            let mut children = children.clone();
+
+
+
+ 142 +
+
+ +
+
+
            children[n] = x;
+
+
+
+ 143 +
+
+ +
+
+
            #[allow(clippy::unwrap_used)]
+
+
+
+ 144 +
+
+ +
+
+
            // We are directly replacing a child so there can't be an error
+
+
+
+ 145 +
+
+ +
+
+
            context(children).unwrap()
+
+
+
+ 146 +
+
+ +
+
+
        }))
+
+
+
+ 147 +
+
+ +
+
+
    }
+
+
+
+ 148 +
+
+ +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/tests/expr_stmt_manual.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/tests/expr_stmt_manual.rs.html new file mode 100644 index 0000000000..a8e2d2dc7e --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/tests/expr_stmt_manual.rs.html @@ -0,0 +1,7225 @@ + + + + + Grcov report - expr_stmt_manual.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
// Expr and Stmt from the paper, manually derived.
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
use std::iter::zip;
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ +
+
+
use im::vector;
+
+
+
+ 6 +
+
+ +
+
+
//use uniplate::test_common::paper::*;
+
+
+
+ 7 +
+
+ +
+
+
use uniplate::biplate::*;
+
+
+
+ 8 +
+
+ +
+
+

+            
+
+
+ 9 +
+
+ +
+
+
use self::Expr::*;
+
+
+
+ 10 +
+
+ +
+
+

+            
+
+
+ 11 +
+
+ +
+
+
// Stmt and Expr to demonstrate and test multitype traversals.
+
+
+
+ 12 +
+
+ +
+
+
#[derive(Eq, PartialEq, Clone, Debug)]
+
+
+
+ 13 +
+
+ +
+
+
pub enum Stmt {
+
+
+
+ 14 +
+
+ +
+
+
    Assign(String, Expr),
+
+
+
+ 15 +
+
+ +
+
+
    Sequence(Vec<Stmt>),
+
+
+
+ 16 +
+
+ +
+
+
    If(Expr, Box<Stmt>, Box<Stmt>),
+
+
+
+ 17 +
+
+ +
+
+
    While(Expr, Box<Stmt>),
+
+
+
+ 18 +
+
+ +
+
+
}
+
+
+
+ 19 +
+
+ +
+
+

+            
+
+
+ 20 +
+
+ +
+
+
#[derive(Eq, PartialEq, Clone, Debug)]
+
+
+
+ 21 +
+
+ +
+
+
pub enum Expr {
+
+
+
+ 22 +
+
+ +
+
+
    Add(Box<Expr>, Box<Expr>),
+
+
+
+ 23 +
+
+ +
+
+
    Sub(Box<Expr>, Box<Expr>),
+
+
+
+ 24 +
+
+ +
+
+
    Mul(Box<Expr>, Box<Expr>),
+
+
+
+ 25 +
+
+ +
+
+
    Div(Box<Expr>, Box<Expr>),
+
+
+
+ 26 +
+
+ +
+
+
    Val(i32),
+
+
+
+ 27 +
+
+ +
+
+
    Var(String),
+
+
+
+ 28 +
+
+ +
+
+
    Neg(Box<Expr>),
+
+
+
+ 29 +
+
+ +
+
+
}
+
+
+
+ 30 +
+
+ +
+
+

+            
+
+
+ 31 +
+
+ +
+
+
impl Uniplate for Expr {
+
+
+
+ 32 +
+
+ 8 +
+
+
    fn uniplate(&self) -> (Tree<Self>, Box<dyn Fn(Tree<Self>) -> Self>) {
+
+
+
+ 33 +
+
+ 8 +
+
+
        match self.clone() {
+
+
+
+ 34 +
+
+ 2 +
+
+
            Add(f0, f1) => {
+
+
+
+ 35 +
+
+ 2 +
+
+
                // Field 0 - Box<Expr>
+
+
+
+ 36 +
+
+ 2 +
+
+
                let (f0_tree, f0_ctx) = <Expr as Biplate<Expr>>::biplate(&*f0);
+
+
+
+ 37 +
+
+ 2 +
+
+

+            
+
+
+ 38 +
+
+ 2 +
+
+
                // Field 1 - Box<Expr>
+
+
+
+ 39 +
+
+ 2 +
+
+
                let (f1_tree, f1_ctx) = <Expr as Biplate<Expr>>::biplate(&*f1);
+
+
+
+ 40 +
+
+ 2 +
+
+

+            
+
+
+ 41 +
+
+ 2 +
+
+
                let tree = Many(vector![f0_tree, f1_tree]);
+
+
+
+ 42 +
+
+ 2 +
+
+
                let ctx = Box::new(move |new_tree| {
+
+
+
+ 43 +
+
+ +
+
+
                    let Many(ts) = new_tree else { panic!() };
+
+
+
+ 44 +
+
+ +
+
+
                    assert_eq!(ts.len(), 2);
+
+
+
+ 45 +
+
+ +
+
+
                    Add(
+
+
+
+ 46 +
+
+ +
+
+
                        Box::new(f0_ctx(ts[0].clone())),
+
+
+
+ 47 +
+
+ +
+
+
                        Box::new(f1_ctx(ts[1].clone())),
+
+
+
+ 48 +
+
+ +
+
+
                    )
+
+
+
+ 49 +
+
+ 2 +
+
+
                });
+
+
+
+ 50 +
+
+ 2 +
+
+

+            
+
+
+ 51 +
+
+ 2 +
+
+
                (tree, ctx)
+
+
+
+ 52 +
+
+ +
+
+
            }
+
+
+
+ 53 +
+
+ +
+
+
            Sub(f0, f1) => {
+
+
+
+ 54 +
+
+ +
+
+
                // Field 0 - Box<Expr>
+
+
+
+ 55 +
+
+ +
+
+
                let (f0_tree, f0_ctx) = <Expr as Biplate<Expr>>::biplate(&*f0);
+
+
+
+ 56 +
+
+ +
+
+

+            
+
+
+ 57 +
+
+ +
+
+
                // Field 1 - Box<Expr>
+
+
+
+ 58 +
+
+ +
+
+
                let (f1_tree, f1_ctx) = <Expr as Biplate<Expr>>::biplate(&*f1);
+
+
+
+ 59 +
+
+ +
+
+

+            
+
+
+ 60 +
+
+ +
+
+
                let tree = Many(vector![f0_tree, f1_tree]);
+
+
+
+ 61 +
+
+ +
+
+
                let ctx = Box::new(move |new_tree| {
+
+
+
+ 62 +
+
+ +
+
+
                    let Many(ts) = new_tree else { panic!() };
+
+
+
+ 63 +
+
+ +
+
+
                    assert_eq!(ts.len(), 2);
+
+
+
+ 64 +
+
+ +
+
+
                    Add(
+
+
+
+ 65 +
+
+ +
+
+
                        Box::new(f0_ctx(ts[0].clone())),
+
+
+
+ 66 +
+
+ +
+
+
                        Box::new(f1_ctx(ts[1].clone())),
+
+
+
+ 67 +
+
+ +
+
+
                    )
+
+
+
+ 68 +
+
+ +
+
+
                });
+
+
+
+ 69 +
+
+ +
+
+

+            
+
+
+ 70 +
+
+ +
+
+
                (tree, ctx)
+
+
+
+ 71 +
+
+ +
+
+
            }
+
+
+
+ 72 +
+
+ +
+
+
            Mul(f0, f1) => {
+
+
+
+ 73 +
+
+ +
+
+
                // Field 0 - Box<Expr>
+
+
+
+ 74 +
+
+ +
+
+
                let (f0_tree, f0_ctx) = <Expr as Biplate<Expr>>::biplate(&*f0);
+
+
+
+ 75 +
+
+ +
+
+

+            
+
+
+ 76 +
+
+ +
+
+
                // Field 1 - Box<Expr>
+
+
+
+ 77 +
+
+ +
+
+
                let (f1_tree, f1_ctx) = <Expr as Biplate<Expr>>::biplate(&*f1);
+
+
+
+ 78 +
+
+ +
+
+

+            
+
+
+ 79 +
+
+ +
+
+
                let tree = Many(vector![f0_tree, f1_tree]);
+
+
+
+ 80 +
+
+ +
+
+
                let ctx = Box::new(move |new_tree| {
+
+
+
+ 81 +
+
+ +
+
+
                    let Many(ts) = new_tree else { panic!() };
+
+
+
+ 82 +
+
+ +
+
+
                    assert_eq!(ts.len(), 2);
+
+
+
+ 83 +
+
+ +
+
+
                    Add(
+
+
+
+ 84 +
+
+ +
+
+
                        Box::new(f0_ctx(ts[0].clone())),
+
+
+
+ 85 +
+
+ +
+
+
                        Box::new(f1_ctx(ts[1].clone())),
+
+
+
+ 86 +
+
+ +
+
+
                    )
+
+
+
+ 87 +
+
+ +
+
+
                });
+
+
+
+ 88 +
+
+ +
+
+

+            
+
+
+ 89 +
+
+ +
+
+
                (tree, ctx)
+
+
+
+ 90 +
+
+ +
+
+
            }
+
+
+
+ 91 +
+
+ +
+
+
            Div(f0, f1) => {
+
+
+
+ 92 +
+
+ +
+
+
                // Field 0 - Box<Expr>
+
+
+
+ 93 +
+
+ +
+
+
                let (f0_tree, f0_ctx) = <Expr as Biplate<Expr>>::biplate(&*f0);
+
+
+
+ 94 +
+
+ +
+
+

+            
+
+
+ 95 +
+
+ +
+
+
                // Field 1 - Box<Expr>
+
+
+
+ 96 +
+
+ +
+
+
                let (f1_tree, f1_ctx) = <Expr as Biplate<Expr>>::biplate(&*f1);
+
+
+
+ 97 +
+
+ +
+
+

+            
+
+
+ 98 +
+
+ +
+
+
                let tree = Many(vector![f0_tree, f1_tree]);
+
+
+
+ 99 +
+
+ +
+
+
                let ctx = Box::new(move |new_tree| {
+
+
+
+ 100 +
+
+ +
+
+
                    let Many(ts) = new_tree else { panic!() };
+
+
+
+ 101 +
+
+ +
+
+
                    assert_eq!(ts.len(), 2);
+
+
+
+ 102 +
+
+ +
+
+
                    Add(
+
+
+
+ 103 +
+
+ +
+
+
                        Box::new(f0_ctx(ts[0].clone())),
+
+
+
+ 104 +
+
+ +
+
+
                        Box::new(f1_ctx(ts[1].clone())),
+
+
+
+ 105 +
+
+ +
+
+
                    )
+
+
+
+ 106 +
+
+ +
+
+
                });
+
+
+
+ 107 +
+
+ +
+
+

+            
+
+
+ 108 +
+
+ +
+
+
                (tree, ctx)
+
+
+
+ 109 +
+
+ +
+
+
            }
+
+
+
+ 110 +
+
+ +
+
+

+            
+
+
+ 111 +
+
+ 3 +
+
+
            Val(f0) => (
+
+
+
+ 112 +
+
+ 3 +
+
+
                Zero,
+
+
+
+ 113 +
+
+ 3 +
+
+
                Box::new(move |x| {
+
+
+
+ 114 +
+
+ +
+
+
                    let Zero = x else { panic!() };
+
+
+
+ 115 +
+
+ +
+
+
                    Val(f0)
+
+
+
+ 116 +
+
+ 3 +
+
+
                }),
+
+
+
+ 117 +
+
+ 3 +
+
+
            ),
+
+
+
+ 118 +
+
+ 3 +
+
+
            Var(f0) => (
+
+
+
+ 119 +
+
+ 3 +
+
+
                Zero,
+
+
+
+ 120 +
+
+ 3 +
+
+
                Box::new(move |x| {
+
+
+
+ 121 +
+
+ +
+
+
                    let Zero = x else { panic!() };
+
+
+
+ 122 +
+
+ +
+
+
                    Var(f0.clone())
+
+
+
+ 123 +
+
+ 3 +
+
+
                }),
+
+
+
+ 124 +
+
+ 3 +
+
+
            ),
+
+
+
+ 125 +
+
+ +
+
+

+            
+
+
+ 126 +
+
+ +
+
+
            Neg(f0) => (
+
+
+
+ 127 +
+
+ +
+
+
                Zero,
+
+
+
+ 128 +
+
+ +
+
+
                Box::new(move |x| {
+
+
+
+ 129 +
+
+ +
+
+
                    let Zero = x else { panic!() };
+
+
+
+ 130 +
+
+ +
+
+
                    Neg(f0.clone())
+
+
+
+ 131 +
+
+ +
+
+
                }),
+
+
+
+ 132 +
+
+ +
+
+
            ),
+
+
+
+ 133 +
+
+ +
+
+
        }
+
+
+
+ 134 +
+
+ 8 +
+
+
    }
+
+
+
+ 135 +
+
+ +
+
+
}
+
+
+
+ 136 +
+
+ +
+
+

+            
+
+
+ 137 +
+
+ +
+
+
impl Biplate<Stmt> for Expr {
+
+
+
+ 138 +
+
+ +
+
+
    fn biplate(&self) -> (Tree<Stmt>, Box<dyn Fn(Tree<Stmt>) -> Expr>) {
+
+
+
+ 139 +
+
+ +
+
+
        // Optimisation - in derivation, build index of types that lead to eachother.
+
+
+
+ 140 +
+
+ +
+
+
        // Walk this graph to generate all "reachable types from expr"
+
+
+
+ 141 +
+
+ +
+
+
        //
+
+
+
+ 142 +
+
+ +
+
+
        // Stmt is not reachable so just return 0.
+
+
+
+ 143 +
+
+ +
+
+
        //
+
+
+
+ 144 +
+
+ +
+
+
        // Paper does this with the combinators!
+
+
+
+ 145 +
+
+ +
+
+
        //
+
+
+
+ 146 +
+
+ +
+
+
        // We may also need this to know what Biplates to derive!
+
+
+
+ 147 +
+
+ +
+
+
        let expr = self.clone();
+
+
+
+ 148 +
+
+ +
+
+
        (
+
+
+
+ 149 +
+
+ +
+
+
            Zero,
+
+
+
+ 150 +
+
+ +
+
+
            Box::new(move |stmt| {
+
+
+
+ 151 +
+
+ +
+
+
                let Zero = stmt else { panic!() };
+
+
+
+ 152 +
+
+ +
+
+
                expr.clone()
+
+
+
+ 153 +
+
+ +
+
+
            }),
+
+
+
+ 154 +
+
+ +
+
+
        )
+
+
+
+ 155 +
+
+ +
+
+
    }
+
+
+
+ 156 +
+
+ +
+
+
}
+
+
+
+ 157 +
+
+ +
+
+

+            
+
+
+ 158 +
+
+ +
+
+
//this is the most interesting example!
+
+
+
+ 159 +
+
+ +
+
+
impl Biplate<Expr> for Stmt {
+
+
+
+ 160 +
+
+ 12 +
+
+
    fn biplate(&self) -> (Tree<Expr>, Box<dyn Fn(Tree<Expr>) -> Stmt>) {
+
+
+
+ 161 +
+
+ 12 +
+
+
        match self.clone() {
+
+
+
+ 162 +
+
+ 4 +
+
+
            Assign(f0, f1) => {
+
+
+
+ 163 +
+
+ 4 +
+
+
                // Field 0 - non recursive (String)
+
+
+
+ 164 +
+
+ 4 +
+
+
                let (f0_tree, f0_ctx) = (
+
+
+
+ 165 +
+
+ 4 +
+
+
                    Tree::<Expr>::Zero,
+
+
+
+ 166 +
+
+ 4 +
+
+
                    Box::new(move |_: Tree<Expr>| f0.clone()),
+
+
+
+ 167 +
+
+ 4 +
+
+
                );
+
+
+
+ 168 +
+
+ 4 +
+
+

+            
+
+
+ 169 +
+
+ 4 +
+
+
                //field 1 - Expr - target type
+
+
+
+ 170 +
+
+ 4 +
+
+
                let (f1_tree, f1_ctx) = <Expr as Biplate<Expr>>::biplate(&f1);
+
+
+
+ 171 +
+
+ 4 +
+
+

+            
+
+
+ 172 +
+
+ 4 +
+
+
                let tree = Tree::<Expr>::Many(vector![f0_tree, f1_tree]);
+
+
+
+ 173 +
+
+ 4 +
+
+

+            
+
+
+ 174 +
+
+ 4 +
+
+
                let ctx = Box::new(move |new_tree| {
+
+
+
+ 175 +
+
+ +
+
+
                    let Many(ts) = new_tree else { panic!() };
+
+
+
+ 176 +
+
+ +
+
+
                    assert_eq!(ts.len(), 2);
+
+
+
+ 177 +
+
+ +
+
+
                    Assign(f0_ctx(ts[0].clone()), f1_ctx(ts[1].clone()))
+
+
+
+ 178 +
+
+ 4 +
+
+
                });
+
+
+
+ 179 +
+
+ 4 +
+
+

+            
+
+
+ 180 +
+
+ 4 +
+
+
                (tree, ctx)
+
+
+
+ 181 +
+
+ +
+
+
            }
+
+
+
+ 182 +
+
+ 4 +
+
+
            Sequence(f0) => {
+
+
+
+ 183 +
+
+ 4 +
+
+
                // Field 0 - Vec<Stmt>
+
+
+
+ 184 +
+
+ 4 +
+
+

+            
+
+
+ 185 +
+
+ 4 +
+
+
                // Get trees and contexts for each element.
+
+
+
+ 186 +
+
+ 4 +
+
+
                let (f0_elems, f0_ctxs): (Vec<Tree<Expr>>, Vec<Box<dyn Fn(Tree<Expr>) -> Stmt>>) =
+
+
+
+ 187 +
+
+ 4 +
+
+
                    f0.into_iter()
+
+
+
+ 188 +
+
+ 4 +
+
+
                        .map(|stmt| <Stmt as Biplate<Expr>>::biplate(&stmt))
+
+
+
+ 189 +
+
+ 4 +
+
+
                        .unzip();
+
+
+
+ 190 +
+
+ 4 +
+
+

+            
+
+
+ 191 +
+
+ 4 +
+
+
                let f0_tree = Many(f0_elems.into());
+
+
+
+ 192 +
+
+ 4 +
+
+
                let f0_ctx: Box<dyn Fn(Tree<Expr>) -> Vec<Stmt>> = Box::new(move |new_tree| {
+
+
+
+ 193 +
+
+ +
+
+
                    let Many(elem_ts) = new_tree else {
+
+
+
+ 194 +
+
+ +
+
+
                        panic!();
+
+
+
+ 195 +
+
+ +
+
+
                    };
+
+
+
+ 196 +
+
+ +
+
+

+            
+
+
+ 197 +
+
+ +
+
+
                    zip(&f0_ctxs, elem_ts).map(|(ctx, t)| (**ctx)(t)).collect()
+
+
+
+ 198 +
+
+ 4 +
+
+
                });
+
+
+
+ 199 +
+
+ 4 +
+
+

+            
+
+
+ 200 +
+
+ 4 +
+
+
                let tree = Many(vector![f0_tree]);
+
+
+
+ 201 +
+
+ 4 +
+
+
                let ctx = Box::new(move |new_tree| {
+
+
+
+ 202 +
+
+ +
+
+
                    let Many(ts) = new_tree else {
+
+
+
+ 203 +
+
+ +
+
+
                        panic!();
+
+
+
+ 204 +
+
+ +
+
+
                    };
+
+
+
+ 205 +
+
+ +
+
+
                    assert_eq!(ts.len(), 1);
+
+
+
+ 206 +
+
+ +
+
+
                    Sequence(f0_ctx(ts[0].clone()))
+
+
+
+ 207 +
+
+ 4 +
+
+
                });
+
+
+
+ 208 +
+
+ 4 +
+
+

+            
+
+
+ 209 +
+
+ 4 +
+
+
                (tree, ctx)
+
+
+
+ 210 +
+
+ +
+
+
            }
+
+
+
+ 211 +
+
+ +
+
+

+            
+
+
+ 212 +
+
+ 2 +
+
+
            If(f0, f1, f2) => {
+
+
+
+ 213 +
+
+ 2 +
+
+
                // Field 0 - Expr
+
+
+
+ 214 +
+
+ 2 +
+
+
                let (f0_tree, f0_ctx) = <Expr as Biplate<Expr>>::biplate(&f0);
+
+
+
+ 215 +
+
+ 2 +
+
+

+            
+
+
+ 216 +
+
+ 2 +
+
+
                // Field 1 - Box::(stmt)
+
+
+
+ 217 +
+
+ 2 +
+
+
                let (f1_tree, f1_ctx) = <Stmt as Biplate<Expr>>::biplate(&*f1);
+
+
+
+ 218 +
+
+ 2 +
+
+

+            
+
+
+ 219 +
+
+ 2 +
+
+
                //Field 2 - Box::(Stmt)
+
+
+
+ 220 +
+
+ 2 +
+
+
                let (f2_tree, f2_ctx) = <Stmt as Biplate<Expr>>::biplate(&*f2);
+
+
+
+ 221 +
+
+ 2 +
+
+

+            
+
+
+ 222 +
+
+ 2 +
+
+
                let tree = Many(vector![f0_tree, f1_tree, f2_tree]);
+
+
+
+ 223 +
+
+ 2 +
+
+
                let ctx = Box::new(move |new_tree| {
+
+
+
+ 224 +
+
+ +
+
+
                    let Many(ts) = new_tree else { panic!() };
+
+
+
+ 225 +
+
+ +
+
+
                    assert_eq!(ts.len(), 3);
+
+
+
+ 226 +
+
+ +
+
+
                    If(
+
+
+
+ 227 +
+
+ +
+
+
                        f0_ctx(ts[0].clone()),
+
+
+
+ 228 +
+
+ +
+
+
                        Box::new(f1_ctx(ts[1].clone())),
+
+
+
+ 229 +
+
+ +
+
+
                        Box::new(f2_ctx(ts[2].clone())),
+
+
+
+ 230 +
+
+ +
+
+
                    )
+
+
+
+ 231 +
+
+ 2 +
+
+
                });
+
+
+
+ 232 +
+
+ 2 +
+
+

+            
+
+
+ 233 +
+
+ 2 +
+
+
                (tree, ctx)
+
+
+
+ 234 +
+
+ +
+
+
            }
+
+
+
+ 235 +
+
+ 2 +
+
+
            While(f0, f1) => {
+
+
+
+ 236 +
+
+ 2 +
+
+
                // Field 0 - Expr
+
+
+
+ 237 +
+
+ 2 +
+
+
                let (f0_tree, f0_ctx) = <Expr as Biplate<Expr>>::biplate(&f0);
+
+
+
+ 238 +
+
+ 2 +
+
+

+            
+
+
+ 239 +
+
+ 2 +
+
+
                //Field 1 - Box::(Stmt)
+
+
+
+ 240 +
+
+ 2 +
+
+
                let (f1_tree, f1_ctx) = <Stmt as Biplate<Expr>>::biplate(&*f1);
+
+
+
+ 241 +
+
+ 2 +
+
+

+            
+
+
+ 242 +
+
+ 2 +
+
+
                let tree = Many(vector![f0_tree, f1_tree]);
+
+
+
+ 243 +
+
+ 2 +
+
+
                let ctx = Box::new(move |new_tree| {
+
+
+
+ 244 +
+
+ +
+
+
                    let Many(ts) = new_tree else { panic!() };
+
+
+
+ 245 +
+
+ +
+
+
                    assert_eq!(ts.len(), 2);
+
+
+
+ 246 +
+
+ +
+
+
                    While(f0_ctx(ts[0].clone()), Box::new(f1_ctx(ts[1].clone())))
+
+
+
+ 247 +
+
+ 2 +
+
+
                });
+
+
+
+ 248 +
+
+ 2 +
+
+

+            
+
+
+ 249 +
+
+ 2 +
+
+
                (tree, ctx)
+
+
+
+ 250 +
+
+ +
+
+
            }
+
+
+
+ 251 +
+
+ +
+
+
        }
+
+
+
+ 252 +
+
+ 12 +
+
+
    }
+
+
+
+ 253 +
+
+ +
+
+
}
+
+
+
+ 254 +
+
+ +
+
+

+            
+
+
+ 255 +
+
+ +
+
+
impl Biplate<Expr> for Expr {
+
+
+
+ 256 +
+
+ 12 +
+
+
    fn biplate(&self) -> (Tree<Expr>, Box<dyn Fn(Tree<Expr>) -> Self>) {
+
+
+
+ 257 +
+
+ 12 +
+
+
        (
+
+
+
+ 258 +
+
+ 12 +
+
+
            One(self.clone()),
+
+
+
+ 259 +
+
+ 12 +
+
+
            Box::new(|t| {
+
+
+
+ 260 +
+
+ +
+
+
                let One(stmt) = t else { panic!() };
+
+
+
+ 261 +
+
+ +
+
+
                stmt
+
+
+
+ 262 +
+
+ 12 +
+
+
            }),
+
+
+
+ 263 +
+
+ 12 +
+
+
        )
+
+
+
+ 264 +
+
+ 12 +
+
+
    }
+
+
+
+ 265 +
+
+ +
+
+
}
+
+
+
+ 266 +
+
+ +
+
+

+            
+
+
+ 267 +
+
+ +
+
+
impl Biplate<Stmt> for Stmt {
+
+
+
+ 268 +
+
+ +
+
+
    fn biplate(&self) -> (Tree<Stmt>, Box<dyn Fn(Tree<Stmt>) -> Self>) {
+
+
+
+ 269 +
+
+ +
+
+
        (
+
+
+
+ 270 +
+
+ +
+
+
            One(self.clone()),
+
+
+
+ 271 +
+
+ +
+
+
            Box::new(|t| {
+
+
+
+ 272 +
+
+ +
+
+
                let One(stmt) = t else { panic!() };
+
+
+
+ 273 +
+
+ +
+
+
                stmt
+
+
+
+ 274 +
+
+ +
+
+
            }),
+
+
+
+ 275 +
+
+ +
+
+
        )
+
+
+
+ 276 +
+
+ +
+
+
    }
+
+
+
+ 277 +
+
+ +
+
+
}
+
+
+
+ 278 +
+
+ +
+
+

+            
+
+
+ 279 +
+
+ +
+
+
use Stmt::*;
+
+
+
+ 280 +
+
+ +
+
+
use Tree::*;
+
+
+
+ 281 +
+
+ +
+
+

+            
+
+
+ 282 +
+
+ +
+
+
impl Uniplate for Stmt {
+
+
+
+ 283 +
+
+ +
+
+
    fn uniplate(&self) -> (Tree<Stmt>, Box<dyn Fn(Tree<Stmt>) -> Stmt>) {
+
+
+
+ 284 +
+
+ +
+
+
        match self.clone() {
+
+
+
+ 285 +
+
+ +
+
+
            Assign(s, expr) => {
+
+
+
+ 286 +
+
+ +
+
+
                // Field 0 - non recursive (String)
+
+
+
+ 287 +
+
+ +
+
+
                let (f0_tree, f0_ctx) =
+
+
+
+ 288 +
+
+ +
+
+
                    (Tree::<Stmt>::Zero, Box::new(move |_: Tree<Stmt>| s.clone()));
+
+
+
+ 289 +
+
+ +
+
+

+            
+
+
+ 290 +
+
+ +
+
+
                // Field 1- ADT (Expr)
+
+
+
+ 291 +
+
+ +
+
+
                let (f1_tree, f1_ctx) = <Expr as Biplate<Stmt>>::biplate(&expr);
+
+
+
+ 292 +
+
+ +
+
+

+            
+
+
+ 293 +
+
+ +
+
+
                // we know there is no path Expr -> Stmt, so we could just inline the zero
+
+
+
+ 294 +
+
+ +
+
+
                // defintion (see Biplate<Stmt> for Expr comments)
+
+
+
+ 295 +
+
+ +
+
+
                // let (f1_tree,f1_ctx) (Zero, Box::new(move |stmt| {let Zero = stmt else {panic!()}; f1.clone()}));
+
+
+
+ 296 +
+
+ +
+
+

+            
+
+
+ 297 +
+
+ +
+
+
                let tree = Many(vector![f0_tree, f1_tree]);
+
+
+
+ 298 +
+
+ +
+
+
                let ctx = Box::new(move |new_tree| {
+
+
+
+ 299 +
+
+ +
+
+
                    let Many(ts) = new_tree else { panic!() };
+
+
+
+ 300 +
+
+ +
+
+
                    assert_eq!(ts.len(), 2);
+
+
+
+ 301 +
+
+ +
+
+
                    Assign(f0_ctx(ts[0].clone()), f1_ctx(ts[1].clone()))
+
+
+
+ 302 +
+
+ +
+
+
                });
+
+
+
+ 303 +
+
+ +
+
+

+            
+
+
+ 304 +
+
+ +
+
+
                (tree, ctx)
+
+
+
+ 305 +
+
+ +
+
+
            }
+
+
+
+ 306 +
+
+ +
+
+
            Sequence(f0) => {
+
+
+
+ 307 +
+
+ +
+
+
                // Field 0 - Vec<Stmt>
+
+
+
+ 308 +
+
+ +
+
+
                // Special case for iterables / lists?
+
+
+
+ 309 +
+
+ +
+
+

+            
+
+
+ 310 +
+
+ +
+
+
                // Get trees and contexts for each element.
+
+
+
+ 311 +
+
+ +
+
+
                let (f0_elems, f0_ctxs): (Vec<Tree<Stmt>>, Vec<Box<dyn Fn(Tree<Stmt>) -> Stmt>>) =
+
+
+
+ 312 +
+
+ +
+
+
                    f0.into_iter()
+
+
+
+ 313 +
+
+ +
+
+
                        .map(|stmt| <Stmt as Biplate<Stmt>>::biplate(&stmt))
+
+
+
+ 314 +
+
+ +
+
+
                        .unzip();
+
+
+
+ 315 +
+
+ +
+
+

+            
+
+
+ 316 +
+
+ +
+
+
                let f0_tree = Many(f0_elems.into());
+
+
+
+ 317 +
+
+ +
+
+
                let f0_ctx: Box<dyn Fn(Tree<Stmt>) -> Vec<Stmt>> = Box::new(move |new_tree| {
+
+
+
+ 318 +
+
+ +
+
+
                    let Many(elem_ts) = new_tree else {
+
+
+
+ 319 +
+
+ +
+
+
                        panic!();
+
+
+
+ 320 +
+
+ +
+
+
                    };
+
+
+
+ 321 +
+
+ +
+
+

+            
+
+
+ 322 +
+
+ +
+
+
                    zip(&f0_ctxs, elem_ts).map(|(ctx, t)| (**ctx)(t)).collect()
+
+
+
+ 323 +
+
+ +
+
+
                });
+
+
+
+ 324 +
+
+ +
+
+

+            
+
+
+ 325 +
+
+ +
+
+
                let tree = Many(vector![f0_tree]);
+
+
+
+ 326 +
+
+ +
+
+
                let ctx = Box::new(move |new_tree| {
+
+
+
+ 327 +
+
+ +
+
+
                    let Many(ts) = new_tree else {
+
+
+
+ 328 +
+
+ +
+
+
                        panic!();
+
+
+
+ 329 +
+
+ +
+
+
                    };
+
+
+
+ 330 +
+
+ +
+
+
                    assert_eq!(ts.len(), 1);
+
+
+
+ 331 +
+
+ +
+
+
                    Sequence(f0_ctx(ts[0].clone()))
+
+
+
+ 332 +
+
+ +
+
+
                });
+
+
+
+ 333 +
+
+ +
+
+

+            
+
+
+ 334 +
+
+ +
+
+
                (tree, ctx)
+
+
+
+ 335 +
+
+ +
+
+
            }
+
+
+
+ 336 +
+
+ +
+
+
            If(f0, f1, f2) => {
+
+
+
+ 337 +
+
+ +
+
+
                // Field 0 - Expr
+
+
+
+ 338 +
+
+ +
+
+
                let (f0_tree, f0_ctx) = <Expr as Biplate<Stmt>>::biplate(&f0);
+
+
+
+ 339 +
+
+ +
+
+

+            
+
+
+ 340 +
+
+ +
+
+
                //field 1 - box::(stmt)
+
+
+
+ 341 +
+
+ +
+
+
                // Treat T, Box<T> as a special case as defining Uniplate and Biplate for Box<T> is
+
+
+
+ 342 +
+
+ +
+
+
                // a lot of moving things from stack to heap and back for no reason.
+
+
+
+ 343 +
+
+ +
+
+
                let (f1_tree, f1_ctx) = <Stmt as Biplate<Stmt>>::biplate(&*f1);
+
+
+
+ 344 +
+
+ +
+
+

+            
+
+
+ 345 +
+
+ +
+
+
                //Field 2 - Box::(Stmt)
+
+
+
+ 346 +
+
+ +
+
+
                let (f2_tree, f2_ctx) = <Stmt as Biplate<Stmt>>::biplate(&*f2);
+
+
+
+ 347 +
+
+ +
+
+

+            
+
+
+ 348 +
+
+ +
+
+
                let tree = Many(vector![f0_tree, f1_tree, f2_tree]);
+
+
+
+ 349 +
+
+ +
+
+
                let ctx = Box::new(move |new_tree| {
+
+
+
+ 350 +
+
+ +
+
+
                    let Many(ts) = new_tree else { panic!() };
+
+
+
+ 351 +
+
+ +
+
+
                    assert_eq!(ts.len(), 3);
+
+
+
+ 352 +
+
+ +
+
+
                    If(
+
+
+
+ 353 +
+
+ +
+
+
                        f0_ctx(ts[0].clone()),
+
+
+
+ 354 +
+
+ +
+
+
                        Box::new(f1_ctx(ts[1].clone())),
+
+
+
+ 355 +
+
+ +
+
+
                        Box::new(f2_ctx(ts[2].clone())),
+
+
+
+ 356 +
+
+ +
+
+
                    )
+
+
+
+ 357 +
+
+ +
+
+
                });
+
+
+
+ 358 +
+
+ +
+
+

+            
+
+
+ 359 +
+
+ +
+
+
                (tree, ctx)
+
+
+
+ 360 +
+
+ +
+
+
            }
+
+
+
+ 361 +
+
+ +
+
+
            While(f0, f1) => {
+
+
+
+ 362 +
+
+ +
+
+
                // Field 0 - Expr
+
+
+
+ 363 +
+
+ +
+
+
                let (f0_tree, f0_ctx) = <Expr as Biplate<Stmt>>::biplate(&f0);
+
+
+
+ 364 +
+
+ +
+
+

+            
+
+
+ 365 +
+
+ +
+
+
                //Field 1 - Box::(Stmt)
+
+
+
+ 366 +
+
+ +
+
+
                let (f1_tree, f1_ctx) = <Stmt as Biplate<Stmt>>::biplate(&*f1);
+
+
+
+ 367 +
+
+ +
+
+

+            
+
+
+ 368 +
+
+ +
+
+
                let tree = Many(vector![f0_tree, f1_tree]);
+
+
+
+ 369 +
+
+ +
+
+
                let ctx = Box::new(move |new_tree| {
+
+
+
+ 370 +
+
+ +
+
+
                    let Many(ts) = new_tree else { panic!() };
+
+
+
+ 371 +
+
+ +
+
+
                    assert_eq!(ts.len(), 2);
+
+
+
+ 372 +
+
+ +
+
+
                    While(f0_ctx(ts[0].clone()), Box::new(f1_ctx(ts[1].clone())))
+
+
+
+ 373 +
+
+ +
+
+
                });
+
+
+
+ 374 +
+
+ +
+
+

+            
+
+
+ 375 +
+
+ +
+
+
                (tree, ctx)
+
+
+
+ 376 +
+
+ +
+
+
            }
+
+
+
+ 377 +
+
+ +
+
+
        }
+
+
+
+ 378 +
+
+ +
+
+
    }
+
+
+
+ 379 +
+
+ +
+
+
}
+
+
+
+ 380 +
+
+ +
+
+

+            
+
+
+ 381 +
+
+ +
+
+
#[test]
+
+
+
+ 382 +
+
+ 1 +
+
+
fn children_bi_multitype() {
+
+
+
+ 383 +
+
+ 1 +
+
+
    let my_stmt = Sequence(vec![
+
+
+
+ 384 +
+
+ 1 +
+
+
        While(
+
+
+
+ 385 +
+
+ 1 +
+
+
            Val(0),
+
+
+
+ 386 +
+
+ 1 +
+
+
            Box::new(Assign(
+
+
+
+ 387 +
+
+ 1 +
+
+
                "x".to_owned(),
+
+
+
+ 388 +
+
+ 1 +
+
+
                Add(Box::new(Var("x".to_owned())), Box::new(Val(10))),
+
+
+
+ 389 +
+
+ 1 +
+
+
            )),
+
+
+
+ 390 +
+
+ 1 +
+
+
        ),
+
+
+
+ 391 +
+
+ 1 +
+
+
        If(
+
+
+
+ 392 +
+
+ 1 +
+
+
            Var("x".to_string()),
+
+
+
+ 393 +
+
+ 1 +
+
+
            Box::new(Assign(
+
+
+
+ 394 +
+
+ 1 +
+
+
                "x".to_string(),
+
+
+
+ 395 +
+
+ 1 +
+
+
                Add(Box::new(Var("x".to_owned())), Box::new(Val(10))),
+
+
+
+ 396 +
+
+ 1 +
+
+
            )),
+
+
+
+ 397 +
+
+ 1 +
+
+
            Box::new(Sequence(vec![])),
+
+
+
+ 398 +
+
+ 1 +
+
+
        ),
+
+
+
+ 399 +
+
+ 1 +
+
+
    ]);
+
+
+
+ 400 +
+
+ 1 +
+
+

+            
+
+
+ 401 +
+
+ 1 +
+
+
    let expected_expr_children = 4;
+
+
+
+ 402 +
+
+ 1 +
+
+

+            
+
+
+ 403 +
+
+ 1 +
+
+
    let children = <Stmt as Biplate<Expr>>::children_bi(&my_stmt);
+
+
+
+ 404 +
+
+ 1 +
+
+

+            
+
+
+ 405 +
+
+ 1 +
+
+
    assert_eq!(expected_expr_children, children.len());
+
+
+
+ 406 +
+
+ +
+
+

+            
+
+
+ 407 +
+
+ 1 +
+
+
    println!("{:?}", children);
+
+
+
+ 408 +
+
+ 1 +
+
+
    let Val(_) = children[0] else { panic!() };
+
+
+
+ 409 +
+
+ 1 +
+
+
    let Add(_, _) = children[1] else { panic!() };
+
+
+
+ 410 +
+
+ 1 +
+
+
    let Var(_) = children[2] else { panic!() };
+
+
+
+ 411 +
+
+ 1 +
+
+
    let Add(_, _) = children[3] else { panic!() };
+
+
+
+ 412 +
+
+ 1 +
+
+
}
+
+
+
+ 413 +
+
+ +
+
+

+            
+
+
+ 414 +
+
+ +
+
+
#[test]
+
+
+
+ 415 +
+
+ 1 +
+
+
fn universe_bi_multitype() {
+
+
+
+ 416 +
+
+ 1 +
+
+
    let my_stmt = Sequence(vec![
+
+
+
+ 417 +
+
+ 1 +
+
+
        While(
+
+
+
+ 418 +
+
+ 1 +
+
+
            Val(0),
+
+
+
+ 419 +
+
+ 1 +
+
+
            Box::new(Assign(
+
+
+
+ 420 +
+
+ 1 +
+
+
                "x".to_owned(),
+
+
+
+ 421 +
+
+ 1 +
+
+
                Add(Box::new(Var("x".to_owned())), Box::new(Val(10))),
+
+
+
+ 422 +
+
+ 1 +
+
+
            )),
+
+
+
+ 423 +
+
+ 1 +
+
+
        ),
+
+
+
+ 424 +
+
+ 1 +
+
+
        If(
+
+
+
+ 425 +
+
+ 1 +
+
+
            Var("x".to_string()),
+
+
+
+ 426 +
+
+ 1 +
+
+
            Box::new(Assign(
+
+
+
+ 427 +
+
+ 1 +
+
+
                "x".to_string(),
+
+
+
+ 428 +
+
+ 1 +
+
+
                Add(Box::new(Var("x".to_owned())), Box::new(Val(10))),
+
+
+
+ 429 +
+
+ 1 +
+
+
            )),
+
+
+
+ 430 +
+
+ 1 +
+
+
            Box::new(Sequence(vec![])),
+
+
+
+ 431 +
+
+ 1 +
+
+
        ),
+
+
+
+ 432 +
+
+ 1 +
+
+
    ]);
+
+
+
+ 433 +
+
+ 1 +
+
+

+            
+
+
+ 434 +
+
+ 1 +
+
+
    let expected_expr_universe = 8;
+
+
+
+ 435 +
+
+ 1 +
+
+

+            
+
+
+ 436 +
+
+ 1 +
+
+
    let children = <Stmt as Biplate<Expr>>::universe_bi(&my_stmt);
+
+
+
+ 437 +
+
+ 1 +
+
+

+            
+
+
+ 438 +
+
+ 1 +
+
+
    assert_eq!(expected_expr_universe, children.len());
+
+
+
+ 439 +
+
+ +
+
+

+            
+
+
+ 440 +
+
+ 1 +
+
+
    println!("{:?}", children);
+
+
+
+ 441 +
+
+ 1 +
+
+
    let Val(_) = children[0] else { panic!() };
+
+
+
+ 442 +
+
+ 1 +
+
+
    let Add(_, _) = children[1] else { panic!() };
+
+
+
+ 443 +
+
+ 1 +
+
+
    let Var(_) = children[2] else { panic!() };
+
+
+
+ 444 +
+
+ 1 +
+
+
    let Val(_) = children[3] else { panic!() };
+
+
+
+ 445 +
+
+ 1 +
+
+
    let Var(_) = children[4] else { panic!() };
+
+
+
+ 446 +
+
+ 1 +
+
+
    let Add(_, _) = children[5] else { panic!() };
+
+
+
+ 447 +
+
+ 1 +
+
+
    let Var(_) = children[6] else { panic!() };
+
+
+
+ 448 +
+
+ 1 +
+
+
    let Val(_) = children[7] else { panic!() };
+
+
+
+ 449 +
+
+ 1 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/tests/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/tests/index.html new file mode 100644 index 0000000000..ff514b76f9 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate/tests/index.html @@ -0,0 +1,74 @@ + + + + + Grcov report - crates/uniplate/tests + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
expr_stmt_manual.rs + + 43.48% + + + 43.48% + + 160 / 368 + 17.65%6 / 34
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/src/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/src/index.html new file mode 100644 index 0000000000..0c17302687 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/src/index.html @@ -0,0 +1,74 @@ + + + + + Grcov report - crates/uniplate_derive/src + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
lib.rs + + 96.9% + + + 96.9% + + 125 / 129 + 51.61%16 / 31
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/src/lib.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/src/lib.rs.html new file mode 100644 index 0000000000..843920c2e9 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/src/lib.rs.html @@ -0,0 +1,3081 @@ + + + + + Grcov report - lib.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use proc_macro::{self, TokenStream};
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
use proc_macro2::TokenStream as TokenStream2;
+
+
+
+ 4 +
+
+ +
+
+
use quote::{format_ident, quote};
+
+
+
+ 5 +
+
+ +
+
+
use syn::{parse_macro_input, Data, DataEnum, DeriveInput, Ident, Variant};
+
+
+
+ 6 +
+
+ +
+
+

+            
+
+
+ 7 +
+
+ +
+
+
use crate::utils::generate::{generate_field_clones, generate_field_fills, generate_field_idents};
+
+
+
+ 8 +
+
+ +
+
+

+            
+
+
+ 9 +
+
+ +
+
+
mod utils;
+
+
+
+ 10 +
+
+ +
+
+

+            
+
+
+ 11 +
+
+ +
+
+
/// Generate the full match pattern for a variant
+
+
+
+ 12 +
+
+ 252 +
+
+
fn generate_match_pattern(variant: &Variant, root_ident: &Ident) -> TokenStream2 {
+
+
+
+ 13 +
+
+ 252 +
+
+
    let field_idents = generate_field_idents(&variant.fields);
+
+
+
+ 14 +
+
+ 252 +
+
+
    let variant_ident = &variant.ident;
+
+
+
+ 15 +
+
+ 252 +
+
+

+            
+
+
+ 16 +
+
+ 252 +
+
+
    if field_idents.is_empty() {
+
+
+
+ 17 +
+
+ 12 +
+
+
        quote! {
+
+
+
+ 18 +
+
+ 12 +
+
+
            #root_ident::#variant_ident
+
+
+
+ 19 +
+
+ 12 +
+
+
        }
+
+
+
+ 20 +
+
+ +
+
+
    } else {
+
+
+
+ 21 +
+
+ 240 +
+
+
        quote! {
+
+
+
+ 22 +
+
+ 240 +
+
+
            #root_ident::#variant_ident(#(#field_idents,)*)
+
+
+
+ 23 +
+
+ 240 +
+
+
        }
+
+
+
+ 24 +
+
+ +
+
+
    }
+
+
+
+ 25 +
+
+ 252 +
+
+
}
+
+
+
+ 26 +
+
+ +
+
+

+            
+
+
+ 27 +
+
+ +
+
+
/// Generate the code to get the children of a variant
+
+
+
+ 28 +
+
+ 126 +
+
+
fn generate_variant_children_match_arm(variant: &Variant, root_ident: &Ident) -> TokenStream2 {
+
+
+
+ 29 +
+
+ 126 +
+
+
    let field_clones = generate_field_clones(&variant.fields, root_ident);
+
+
+
+ 30 +
+
+ 126 +
+
+

+            
+
+
+ 31 +
+
+ 126 +
+
+
    let match_pattern = generate_match_pattern(variant, root_ident);
+
+
+
+ 32 +
+
+ +
+
+

+            
+
+
+ 33 +
+
+ 126 +
+
+
    let clones = if field_clones.is_empty() {
+
+
+
+ 34 +
+
+ 20 +
+
+
        quote! {
+
+
+
+ 35 +
+
+ 20 +
+
+
            Vec::new()
+
+
+
+ 36 +
+
+ 20 +
+
+
        }
+
+
+
+ 37 +
+
+ +
+
+
    } else {
+
+
+
+ 38 +
+
+ 106 +
+
+
        quote! {
+
+
+
+ 39 +
+
+ 106 +
+
+
            vec![#(#field_clones,)*].iter().flatten().cloned().collect::<Vec<_>>()
+
+
+
+ 40 +
+
+ 106 +
+
+
        }
+
+
+
+ 41 +
+
+ +
+
+
    };
+
+
+
+ 42 +
+
+ +
+
+

+            
+
+
+ 43 +
+
+ 126 +
+
+
    let mach_arm = quote! {
+
+
+
+ 44 +
+
+ 126 +
+
+
         #match_pattern => {
+
+
+
+ 45 +
+
+ 126 +
+
+
            #clones
+
+
+
+ 46 +
+
+ 126 +
+
+
        }
+
+
+
+ 47 +
+
+ 126 +
+
+
    };
+
+
+
+ 48 +
+
+ 126 +
+
+

+            
+
+
+ 49 +
+
+ 126 +
+
+
    mach_arm
+
+
+
+ 50 +
+
+ 126 +
+
+
}
+
+
+
+ 51 +
+
+ +
+
+

+            
+
+
+ 52 +
+
+ +
+
+
/// Generate an implementation of `context` for a variant
+
+
+
+ 53 +
+
+ 126 +
+
+
fn generate_variant_context_match_arm(variant: &Variant, root_ident: &Ident) -> TokenStream2 {
+
+
+
+ 54 +
+
+ 126 +
+
+
    let variant_ident = &variant.ident;
+
+
+
+ 55 +
+
+ 126 +
+
+
    let children_ident = Ident::new("children", variant_ident.span());
+
+
+
+ 56 +
+
+ 126 +
+
+
    let field_fills = generate_field_fills(&variant.fields, root_ident, &children_ident);
+
+
+
+ 57 +
+
+ 126 +
+
+
    let error_ident = format_ident!("UniplateError{}", root_ident);
+
+
+
+ 58 +
+
+ 126 +
+
+
    let match_pattern = generate_match_pattern(variant, root_ident);
+
+
+
+ 59 +
+
+ 126 +
+
+

+            
+
+
+ 60 +
+
+ 126 +
+
+
    if field_fills.is_empty() {
+
+
+
+ 61 +
+
+ 6 +
+
+
        quote! {
+
+
+
+ 62 +
+
+ 6 +
+
+
            #match_pattern => {
+
+
+
+ 63 +
+
+ 6 +
+
+
                Box::new(|_| Ok(#root_ident::#variant_ident))
+
+
+
+ 64 +
+
+ 6 +
+
+
            }
+
+
+
+ 65 +
+
+ 6 +
+
+
        }
+
+
+
+ 66 +
+
+ +
+
+
    } else {
+
+
+
+ 67 +
+
+ 120 +
+
+
        quote! {
+
+
+
+ 68 +
+
+ 120 +
+
+
            #match_pattern => {
+
+
+
+ 69 +
+
+ 120 +
+
+
                Box::new(|children| {
+
+
+
+ 70 +
+
+ 120 +
+
+
                    if (children.len() != self.children().len()) {
+
+
+
+ 71 +
+
+ 120 +
+
+
                        return Err(#error_ident::WrongNumberOfChildren(self.children().len(), children.len()));
+
+
+
+ 72 +
+
+ 120 +
+
+
                    }
+
+
+
+ 73 +
+
+ 120 +
+
+

+            
+
+
+ 74 +
+
+ 120 +
+
+
                    let mut #children_ident = children.clone();
+
+
+
+ 75 +
+
+ 120 +
+
+
                    Ok(#root_ident::#variant_ident(#(#field_fills,)*))
+
+
+
+ 76 +
+
+ 120 +
+
+
                })
+
+
+
+ 77 +
+
+ 120 +
+
+
            }
+
+
+
+ 78 +
+
+ 120 +
+
+
        }
+
+
+
+ 79 +
+
+ +
+
+
    }
+
+
+
+ 80 +
+
+ 126 +
+
+
}
+
+
+
+ 81 +
+
+ +
+
+

+            
+
+
+ 82 +
+
+ +
+
+
/// Derive the `Uniplate` trait for an arbitrary type
+
+
+
+ 83 +
+
+ +
+
+
///
+
+
+
+ 84 +
+
+ +
+
+
/// # WARNING
+
+
+
+ 85 +
+
+ +
+
+
///
+
+
+
+ 86 +
+
+ +
+
+
/// This is alpha code. It is not yet stable and some features are missing.
+
+
+
+ 87 +
+
+ +
+
+
///
+
+
+
+ 88 +
+
+ +
+
+
/// ## What works?
+
+
+
+ 89 +
+
+ +
+
+
///
+
+
+
+ 90 +
+
+ +
+
+
/// - Deriving `Uniplate` for enum types
+
+
+
+ 91 +
+
+ +
+
+
/// - `Box<T>` and `Vec<T>` fields, including nested vectors
+
+
+
+ 92 +
+
+ +
+
+
/// - Tuple fields, including nested tuples - e.g. `(Vec<T>, (Box<T>, i32))`
+
+
+
+ 93 +
+
+ +
+
+
///
+
+
+
+ 94 +
+
+ +
+
+
/// ## What does not work?
+
+
+
+ 95 +
+
+ +
+
+
///
+
+
+
+ 96 +
+
+ +
+
+
/// - Structs
+
+
+
+ 97 +
+
+ +
+
+
/// - Unions
+
+
+
+ 98 +
+
+ +
+
+
/// - Array fields
+
+
+
+ 99 +
+
+ +
+
+
/// - Multiple type arguments - e.g. `MyType<T, R>`
+
+
+
+ 100 +
+
+ +
+
+
/// - Any complex type arguments, e.g. `MyType<T: MyTrait1 + MyTrait2>`
+
+
+
+ 101 +
+
+ +
+
+
/// - Any collection type other than `Vec`
+
+
+
+ 102 +
+
+ +
+
+
/// - Any box type other than `Box`
+
+
+
+ 103 +
+
+ +
+
+
///
+
+
+
+ 104 +
+
+ +
+
+
/// # Usage
+
+
+
+ 105 +
+
+ +
+
+
///
+
+
+
+ 106 +
+
+ +
+
+
/// This macro is intended to replace a hand-coded implementation of the `Uniplate` trait.
+
+
+
+ 107 +
+
+ +
+
+
/// Example:
+
+
+
+ 108 +
+
+ +
+
+
///
+
+
+
+ 109 +
+
+ +
+
+
/// ```rust
+
+
+
+ 110 +
+
+ 1 +
+
+
/// use uniplate_derive::Uniplate;
+
+
+
+ 111 +
+
+ 1 +
+
+
/// use uniplate::uniplate::Uniplate;
+
+
+
+ 112 +
+
+ 1 +
+
+
///
+
+
+
+ 113 +
+
+ 1 +
+
+
/// #[derive(PartialEq, Eq, Debug, Clone, Uniplate)]
+
+
+
+ 114 +
+
+ 3 +
+
+
/// enum MyEnum {
+
+
+
+ 115 +
+
+ 1 +
+
+
///    A(Box<MyEnum>),
+
+
+
+ 116 +
+
+ 1 +
+
+
///    B(Vec<MyEnum>),
+
+
+
+ 117 +
+
+ 1 +
+
+
///    C(i32),
+
+
+
+ 118 +
+
+ 1 +
+
+
/// }
+
+
+
+ 119 +
+
+ 1 +
+
+
///
+
+
+
+ 120 +
+
+ 1 +
+
+
/// let a = MyEnum::A(Box::new(MyEnum::C(42)));
+
+
+
+ 121 +
+
+ 1 +
+
+
/// let (children, context) = a.uniplate();
+
+
+
+ 122 +
+
+ 1 +
+
+
/// assert_eq!(children, vec![MyEnum::C(42)]);
+
+
+
+ 123 +
+
+ 1 +
+
+
/// assert_eq!(context(vec![MyEnum::C(42)]).unwrap(), a);
+
+
+
+ 124 +
+
+ 1 +
+
+
/// ```
+
+
+
+ 125 +
+
+ 1 +
+
+
///
+
+
+
+ 126 +
+
+ +
+
+
#[proc_macro_derive(Uniplate)]
+
+
+
+ 127 +
+
+ 8 +
+
+
pub fn derive(macro_input: TokenStream) -> TokenStream {
+
+
+
+ 128 +
+
+ 8 +
+
+
    let input = parse_macro_input!(macro_input as DeriveInput);
+
+
+
+ 129 +
+
+ 8 +
+
+
    let root_ident = &input.ident;
+
+
+
+ 130 +
+
+ 8 +
+
+
    let data = &input.data;
+
+
+
+ 131 +
+
+ +
+
+

+            
+
+
+ 132 +
+
+ 8 +
+
+
    let children_impl: TokenStream2 = match data {
+
+
+
+ 133 +
+
+ +
+
+
        Data::Struct(_) => unimplemented!("Structs currently not supported"), // ToDo support structs
+
+
+
+ 134 +
+
+ +
+
+
        Data::Union(_) => unimplemented!("Unions currently not supported"),   // ToDo support unions
+
+
+
+ 135 +
+
+ 8 +
+
+
        Data::Enum(DataEnum { variants, .. }) => {
+
+
+
+ 136 +
+
+ 8 +
+
+
            let match_arms: Vec<TokenStream2> = variants
+
+
+
+ 137 +
+
+ 8 +
+
+
                .iter()
+
+
+
+ 138 +
+
+ 126 +
+
+
                .map(|vt| generate_variant_children_match_arm(vt, root_ident))
+
+
+
+ 139 +
+
+ 8 +
+
+
                .collect::<Vec<_>>();
+
+
+
+ 140 +
+
+ +
+
+

+            
+
+
+ 141 +
+
+ 8 +
+
+
            let match_statement = quote! {
+
+
+
+ 142 +
+
+ 8 +
+
+
                match self {
+
+
+
+ 143 +
+
+ 8 +
+
+
                    #(#match_arms)*
+
+
+
+ 144 +
+
+ 8 +
+
+
                }
+
+
+
+ 145 +
+
+ 8 +
+
+
            };
+
+
+
+ 146 +
+
+ +
+
+

+            
+
+
+ 147 +
+
+ 8 +
+
+
            match_statement
+
+
+
+ 148 +
+
+ +
+
+
        }
+
+
+
+ 149 +
+
+ +
+
+
    };
+
+
+
+ 150 +
+
+ +
+
+

+            
+
+
+ 151 +
+
+ 8 +
+
+
    let context_impl = match data {
+
+
+
+ 152 +
+
+ +
+
+
        Data::Struct(_) => unimplemented!("Structs currently not supported"),
+
+
+
+ 153 +
+
+ +
+
+
        Data::Union(_) => unimplemented!("Unions currently not supported"),
+
+
+
+ 154 +
+
+ 8 +
+
+
        Data::Enum(DataEnum { variants, .. }) => {
+
+
+
+ 155 +
+
+ 8 +
+
+
            let match_arms: Vec<TokenStream2> = variants
+
+
+
+ 156 +
+
+ 8 +
+
+
                .iter()
+
+
+
+ 157 +
+
+ 126 +
+
+
                .map(|vt| generate_variant_context_match_arm(vt, root_ident))
+
+
+
+ 158 +
+
+ 8 +
+
+
                .collect::<Vec<_>>();
+
+
+
+ 159 +
+
+ +
+
+

+            
+
+
+ 160 +
+
+ 8 +
+
+
            let match_statement = quote! {
+
+
+
+ 161 +
+
+ 8 +
+
+
                match self {
+
+
+
+ 162 +
+
+ 8 +
+
+
                    #(#match_arms)*
+
+
+
+ 163 +
+
+ 8 +
+
+
                }
+
+
+
+ 164 +
+
+ 8 +
+
+
            };
+
+
+
+ 165 +
+
+ +
+
+

+            
+
+
+ 166 +
+
+ 8 +
+
+
            match_statement
+
+
+
+ 167 +
+
+ 8 +
+
+
        }
+
+
+
+ 168 +
+
+ 8 +
+
+
    };
+
+
+
+ 169 +
+
+ 8 +
+
+

+            
+
+
+ 170 +
+
+ 8 +
+
+
    let error_ident = format_ident!("UniplateError{}", root_ident);
+
+
+
+ 171 +
+
+ 8 +
+
+

+            
+
+
+ 172 +
+
+ 8 +
+
+
    let output = quote! {
+
+
+
+ 173 +
+
+ 8 +
+
+
        use uniplate::uniplate::UniplateError as #error_ident;
+
+
+
+ 174 +
+
+ 8 +
+
+

+            
+
+
+ 175 +
+
+ 8 +
+
+
        impl Uniplate for #root_ident {
+
+
+
+ 176 +
+
+ 8 +
+
+
            #[allow(unused_variables)]
+
+
+
+ 177 +
+
+ 8 +
+
+
            fn uniplate(&self) -> (Vec<#root_ident>, Box<dyn Fn(Vec<#root_ident>) -> Result<#root_ident, #error_ident> + '_>) {
+
+
+
+ 178 +
+
+ 8 +
+
+
                let context: Box<dyn Fn(Vec<#root_ident>) -> Result<#root_ident, #error_ident>> = #context_impl;
+
+
+
+ 179 +
+
+ 8 +
+
+

+            
+
+
+ 180 +
+
+ 8 +
+
+
                let children: Vec<#root_ident> = #children_impl;
+
+
+
+ 181 +
+
+ 8 +
+
+

+            
+
+
+ 182 +
+
+ 8 +
+
+
                (children, context)
+
+
+
+ 183 +
+
+ 8 +
+
+
            }
+
+
+
+ 184 +
+
+ 8 +
+
+
        }
+
+
+
+ 185 +
+
+ 8 +
+
+
    };
+
+
+
+ 186 +
+
+ 8 +
+
+

+            
+
+
+ 187 +
+
+ 8 +
+
+
    // println!("Final macro output:\n{}", output.to_string());
+
+
+
+ 188 +
+
+ 8 +
+
+

+            
+
+
+ 189 +
+
+ 8 +
+
+
    output.into()
+
+
+
+ 190 +
+
+ 8 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/src/utils/generate.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/src/utils/generate.rs.html new file mode 100644 index 0000000000..9b2422b219 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/src/utils/generate.rs.html @@ -0,0 +1,3001 @@ + + + + + Grcov report - generate.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use proc_macro2::{Ident, Literal, TokenStream as TokenStream2};
+
+
+
+ 2 +
+
+ +
+
+
use quote::{quote, ToTokens};
+
+
+
+ 3 +
+
+ +
+
+
use syn::spanned::Spanned;
+
+
+
+ 4 +
+
+ +
+
+
use syn::{Field, Fields};
+
+
+
+ 5 +
+
+ +
+
+

+            
+
+
+ 6 +
+
+ +
+
+
use crate::utils::parse::{check_field_type, parse_field_type, UniplateField};
+
+
+
+ 7 +
+
+ +
+
+

+            
+
+
+ 8 +
+
+ +
+
+
/// Generate the code to fill a field in a variant
+
+
+
+ 9 +
+
+ 481 +
+
+
fn get_fill(
+
+
+
+ 10 +
+
+ 481 +
+
+
    ft: &UniplateField,
+
+
+
+ 11 +
+
+ 481 +
+
+
    exprs_ident: &Ident,
+
+
+
+ 12 +
+
+ 481 +
+
+
    field_ident: &TokenStream2,
+
+
+
+ 13 +
+
+ 481 +
+
+
    root_ident: &Ident,
+
+
+
+ 14 +
+
+ 481 +
+
+
) -> TokenStream2 {
+
+
+
+ 15 +
+
+ 481 +
+
+
    if check_field_type(ft, root_ident) {
+
+
+
+ 16 +
+
+ +
+
+
        // If the field or at least one of its children is a type we want to fill
+
+
+
+ 17 +
+
+ 356 +
+
+
        match ft {
+
+
+
+ 18 +
+
+ +
+
+
            UniplateField::Identifier(_) => {
+
+
+
+ 19 +
+
+ 176 +
+
+
                return quote! {
+
+
+
+ 20 +
+
+ 176 +
+
+
                    #exprs_ident.remove(0) // If it is an identifier, take the next child from the list
+
+
+
+ 21 +
+
+ 176 +
+
+
                };
+
+
+
+ 22 +
+
+ +
+
+
            }
+
+
+
+ 23 +
+
+ 123 +
+
+
            UniplateField::Box(_, subfield) => {
+
+
+
+ 24 +
+
+ 123 +
+
+
                let sf = subfield.as_ref();
+
+
+
+ 25 +
+
+ 123 +
+
+
                let sf_fill = get_fill(sf, exprs_ident, field_ident, root_ident);
+
+
+
+ 26 +
+
+ 123 +
+
+
                return quote! {
+
+
+
+ 27 +
+
+ 123 +
+
+
                    Box::new(#sf_fill) // If it is a box, generate the fill for the inner type and box it
+
+
+
+ 28 +
+
+ 123 +
+
+
                };
+
+
+
+ 29 +
+
+ +
+
+
            }
+
+
+
+ 30 +
+
+ 54 +
+
+
            UniplateField::Vector(_, subfield) => {
+
+
+
+ 31 +
+
+ 54 +
+
+
                let sf = subfield.as_ref();
+
+
+
+ 32 +
+
+ 54 +
+
+
                let sf_fill = get_fill(sf, exprs_ident, field_ident, root_ident);
+
+
+
+ 33 +
+
+ 54 +
+
+
                return quote! { // The size is not known at compile time, so generate a loop to fill the vector (using the appropriate fill for the inner type)
+
+
+
+ 34 +
+
+ 54 +
+
+
                    {
+
+
+
+ 35 +
+
+ 54 +
+
+
                        let mut elems: Vec<_> = Vec::new();
+
+
+
+ 36 +
+
+ 54 +
+
+
                        for i in 0..#field_ident.len() { // The length of vectors must not change, so we can use the length of the field to determine how many children to take
+
+
+
+ 37 +
+
+ 54 +
+
+
                            elems.push(#sf_fill)
+
+
+
+ 38 +
+
+ 54 +
+
+
                        }
+
+
+
+ 39 +
+
+ 54 +
+
+
                        elems
+
+
+
+ 40 +
+
+ 54 +
+
+
                    }
+
+
+
+ 41 +
+
+ 54 +
+
+
                };
+
+
+
+ 42 +
+
+ +
+
+
            }
+
+
+
+ 43 +
+
+ 3 +
+
+
            UniplateField::Tuple(_, sfs) => {
+
+
+
+ 44 +
+
+ 3 +
+
+
                let mut sf_fills: Vec<TokenStream2> = Vec::new();
+
+
+
+ 45 +
+
+ +
+
+

+            
+
+
+ 46 +
+
+ 6 +
+
+
                for (i, sf) in sfs.iter().enumerate() {
+
+
+
+ 47 +
+
+ 6 +
+
+
                    // Recursively generate the fill for each field in the tuple
+
+
+
+ 48 +
+
+ 6 +
+
+
                    let i_literal = Literal::usize_unsuffixed(i);
+
+
+
+ 49 +
+
+ 6 +
+
+
                    let sf_ident = quote! {
+
+
+
+ 50 +
+
+ 6 +
+
+
                        #field_ident.#i_literal
+
+
+
+ 51 +
+
+ 6 +
+
+
                    };
+
+
+
+ 52 +
+
+ 6 +
+
+
                    sf_fills.push(get_fill(sf, exprs_ident, &sf_ident, root_ident));
+
+
+
+ 53 +
+
+ 6 +
+
+
                }
+
+
+
+ 54 +
+
+ +
+
+

+            
+
+
+ 55 +
+
+ 3 +
+
+
                return quote! {
+
+
+
+ 56 +
+
+ 3 +
+
+
                    (#(#sf_fills,)*) // Wrap the fills in a tuple
+
+
+
+ 57 +
+
+ 3 +
+
+
                };
+
+
+
+ 58 +
+
+ +
+
+
            }
+
+
+
+ 59 +
+
+ +
+
+
            UniplateField::Array(_, _, _) => {
+
+
+
+ 60 +
+
+ +
+
+
                unimplemented!("Arrays not currently supported") // ToDo support arrays
+
+
+
+ 61 +
+
+ +
+
+
            }
+
+
+
+ 62 +
+
+ +
+
+
            UniplateField::Unknown(_) => {}
+
+
+
+ 63 +
+
+ +
+
+
        }
+
+
+
+ 64 +
+
+ 125 +
+
+
    }
+
+
+
+ 65 +
+
+ +
+
+

+            
+
+
+ 66 +
+
+ 125 +
+
+
    quote! {
+
+
+
+ 67 +
+
+ 125 +
+
+
        #field_ident.clone() // If the field is not a type we want to fill, just keep it
+
+
+
+ 68 +
+
+ 125 +
+
+
    }
+
+
+
+ 69 +
+
+ 481 +
+
+
}
+
+
+
+ 70 +
+
+ +
+
+

+            
+
+
+ 71 +
+
+ +
+
+
/// Generate the code to clone a field in a variant
+
+
+
+ 72 +
+
+ 481 +
+
+
fn get_clone(
+
+
+
+ 73 +
+
+ 481 +
+
+
    ft: &UniplateField,
+
+
+
+ 74 +
+
+ 481 +
+
+
    field_ident: TokenStream2,
+
+
+
+ 75 +
+
+ 481 +
+
+
    root_ident: &Ident,
+
+
+
+ 76 +
+
+ 481 +
+
+
) -> Option<TokenStream2> {
+
+
+
+ 77 +
+
+ 481 +
+
+
    if check_field_type(ft, root_ident) {
+
+
+
+ 78 +
+
+ +
+
+
        // If the field or at least one of its children is a type we want to clone
+
+
+
+ 79 +
+
+ 356 +
+
+
        match ft {
+
+
+
+ 80 +
+
+ +
+
+
            UniplateField::Identifier(_) => {
+
+
+
+ 81 +
+
+ 176 +
+
+
                return Some(quote! {
+
+
+
+ 82 +
+
+ 176 +
+
+
                    vec![#field_ident.clone()] // If it is an identifier, clone it. We still need to wrap it in a vec to use .flatten() on the final list.
+
+
+
+ 83 +
+
+ 176 +
+
+
                });
+
+
+
+ 84 +
+
+ +
+
+
            }
+
+
+
+ 85 +
+
+ 123 +
+
+
            UniplateField::Box(_, inner) => {
+
+
+
+ 86 +
+
+ 123 +
+
+
                let sf = inner.as_ref();
+
+
+
+ 87 +
+
+ 123 +
+
+
                let box_clone = quote! { // Generate the prefix for getting the inner type out of the box
+
+
+
+ 88 +
+
+ 123 +
+
+
                    #field_ident.as_ref().clone()
+
+
+
+ 89 +
+
+ 123 +
+
+
                };
+
+
+
+ 90 +
+
+ 123 +
+
+
                return get_clone(sf, box_clone, root_ident); // Then generate the clone for the inner type
+
+
+
+ 91 +
+
+ +
+
+
            }
+
+
+
+ 92 +
+
+ 54 +
+
+
            UniplateField::Vector(_, inner) => {
+
+
+
+ 93 +
+
+ 54 +
+
+
                let sf = inner.as_ref();
+
+
+
+ 94 +
+
+ 54 +
+
+

+            
+
+
+ 95 +
+
+ 54 +
+
+
                let sf_ident = Ident::new("sf", sf.span()).into_token_stream(); // Identity for the subfields
+
+
+
+ 96 +
+
+ 54 +
+
+
                let sf_clone = get_clone(sf, sf_ident, root_ident); // Clone for the subfields
+
+
+
+ 97 +
+
+ 54 +
+
+

+            
+
+
+ 98 +
+
+ 54 +
+
+
                return Some(quote! {
+
+
+
+ 99 +
+
+ 54 +
+
+
                    #field_ident.iter().flat_map(|sf| #sf_clone).collect::<Vec<_>>() // If it is a vector, generate the clone for the inner type and flatten the list
+
+
+
+ 100 +
+
+ 54 +
+
+
                });
+
+
+
+ 101 +
+
+ +
+
+
            }
+
+
+
+ 102 +
+
+ 3 +
+
+
            UniplateField::Tuple(_, sfs) => {
+
+
+
+ 103 +
+
+ 3 +
+
+
                let mut sf_clones: Vec<TokenStream2> = Vec::new();
+
+
+
+ 104 +
+
+ +
+
+

+            
+
+
+ 105 +
+
+ 6 +
+
+
                for (i, sf) in sfs.iter().enumerate() {
+
+
+
+ 106 +
+
+ +
+
+
                    // Recursively generate the clone for each field in the tuple
+
+
+
+ 107 +
+
+ 6 +
+
+
                    let i_literal = Literal::usize_unsuffixed(i);
+
+
+
+ 108 +
+
+ 6 +
+
+
                    let sf_ident = quote! {
+
+
+
+ 109 +
+
+ 6 +
+
+
                        #field_ident.#i_literal
+
+
+
+ 110 +
+
+ 6 +
+
+
                    };
+
+
+
+ 111 +
+
+ 6 +
+
+
                    let sf_clone = get_clone(sf, sf_ident, root_ident);
+
+
+
+ 112 +
+
+ 6 +
+
+
                    match sf_clone {
+
+
+
+ 113 +
+
+ 1 +
+
+
                        None => {}
+
+
+
+ 114 +
+
+ 5 +
+
+
                        Some(sfc) => sf_clones.push(sfc),
+
+
+
+ 115 +
+
+ +
+
+
                    }
+
+
+
+ 116 +
+
+ +
+
+
                }
+
+
+
+ 117 +
+
+ +
+
+

+            
+
+
+ 118 +
+
+ 3 +
+
+
                return Some(quote! { // Clone the subfields into a vec and flatten
+
+
+
+ 119 +
+
+ 3 +
+
+
                    vec![#(#sf_clones,)*].iter().flatten().cloned().collect::<Vec<_>>()
+
+
+
+ 120 +
+
+ 3 +
+
+
                });
+
+
+
+ 121 +
+
+ +
+
+
            }
+
+
+
+ 122 +
+
+ +
+
+
            UniplateField::Array(_, _, _) => {
+
+
+
+ 123 +
+
+ +
+
+
                // ToDo support arrays
+
+
+
+ 124 +
+
+ +
+
+
                unimplemented!("Arrays not currently supported")
+
+
+
+ 125 +
+
+ +
+
+
            }
+
+
+
+ 126 +
+
+ +
+
+
            UniplateField::Unknown(_) => {} // Ignore unknown types
+
+
+
+ 127 +
+
+ +
+
+
        }
+
+
+
+ 128 +
+
+ 125 +
+
+
    }
+
+
+
+ 129 +
+
+ +
+
+

+            
+
+
+ 130 +
+
+ 125 +
+
+
    None // If the field is not a type we want to clone, return None
+
+
+
+ 131 +
+
+ 481 +
+
+
}
+
+
+
+ 132 +
+
+ +
+
+

+            
+
+
+ 133 +
+
+ +
+
+
/// Helper function to get the name of a field - if it has no name, use `field{idx}`
+
+
+
+ 134 +
+
+ 1192 +
+
+
fn get_field_name(field: &Field, idx: usize) -> String {
+
+
+
+ 135 +
+
+ 1192 +
+
+
    match &field.ident {
+
+
+
+ 136 +
+
+ 1192 +
+
+
        None => format!("field{}", idx),
+
+
+
+ 137 +
+
+ +
+
+
        Some(ident) => ident.to_string(),
+
+
+
+ 138 +
+
+ +
+
+
    }
+
+
+
+ 139 +
+
+ 1192 +
+
+
}
+
+
+
+ 140 +
+
+ +
+
+

+            
+
+
+ 141 +
+
+ +
+
+
/// Generate the code to match the fields of a variant
+
+
+
+ 142 +
+
+ 252 +
+
+
pub fn generate_field_idents(fields: &Fields) -> Vec<TokenStream2> {
+
+
+
+ 143 +
+
+ 252 +
+
+
    return fields
+
+
+
+ 144 +
+
+ 252 +
+
+
        .iter()
+
+
+
+ 145 +
+
+ 252 +
+
+
        .enumerate()
+
+
+
+ 146 +
+
+ 596 +
+
+
        .map(|(idx, field)| {
+
+
+
+ 147 +
+
+ 596 +
+
+
            let field_name = get_field_name(field, idx);
+
+
+
+ 148 +
+
+ 596 +
+
+
            Ident::new(&field_name, field.ident.span()).into_token_stream()
+
+
+
+ 149 +
+
+ 596 +
+
+
        })
+
+
+
+ 150 +
+
+ 252 +
+
+
        .collect();
+
+
+
+ 151 +
+
+ 252 +
+
+
}
+
+
+
+ 152 +
+
+ +
+
+

+            
+
+
+ 153 +
+
+ +
+
+
/// Generate the code to clone the fields of a variant
+
+
+
+ 154 +
+
+ 126 +
+
+
pub fn generate_field_clones(fields: &Fields, root_ident: &Ident) -> Vec<TokenStream2> {
+
+
+
+ 155 +
+
+ 126 +
+
+
    return fields
+
+
+
+ 156 +
+
+ 126 +
+
+
        .iter()
+
+
+
+ 157 +
+
+ 126 +
+
+
        .enumerate()
+
+
+
+ 158 +
+
+ 298 +
+
+
        .filter_map(|(idx, field)| {
+
+
+
+ 159 +
+
+ 298 +
+
+
            let field_name = get_field_name(field, idx);
+
+
+
+ 160 +
+
+ 298 +
+
+
            let field_type = parse_field_type(&field.ty);
+
+
+
+ 161 +
+
+ 298 +
+
+
            let field_ident = Ident::new(&field_name, field.ident.span()).into_token_stream();
+
+
+
+ 162 +
+
+ 298 +
+
+

+            
+
+
+ 163 +
+
+ 298 +
+
+
            get_clone(&field_type, field_ident, root_ident)
+
+
+
+ 164 +
+
+ 298 +
+
+
        })
+
+
+
+ 165 +
+
+ 126 +
+
+
        .collect();
+
+
+
+ 166 +
+
+ 126 +
+
+
}
+
+
+
+ 167 +
+
+ +
+
+

+            
+
+
+ 168 +
+
+ +
+
+
/// Generate the code to fill the fields of a variant
+
+
+
+ 169 +
+
+ 126 +
+
+
pub fn generate_field_fills(
+
+
+
+ 170 +
+
+ 126 +
+
+
    fields: &Fields,
+
+
+
+ 171 +
+
+ 126 +
+
+
    root_ident: &Ident,
+
+
+
+ 172 +
+
+ 126 +
+
+
    exprs_ident: &Ident,
+
+
+
+ 173 +
+
+ 126 +
+
+
) -> Vec<TokenStream2> {
+
+
+
+ 174 +
+
+ 126 +
+
+
    return fields
+
+
+
+ 175 +
+
+ 126 +
+
+
        .iter()
+
+
+
+ 176 +
+
+ 126 +
+
+
        .enumerate()
+
+
+
+ 177 +
+
+ 298 +
+
+
        .map(|(idx, field)| {
+
+
+
+ 178 +
+
+ 298 +
+
+
            let field_name = get_field_name(field, idx);
+
+
+
+ 179 +
+
+ 298 +
+
+
            let field_type = parse_field_type(&field.ty);
+
+
+
+ 180 +
+
+ 298 +
+
+
            let field_ident = Ident::new(&field_name, field.ident.span()).into_token_stream();
+
+
+
+ 181 +
+
+ 298 +
+
+

+            
+
+
+ 182 +
+
+ 298 +
+
+
            get_fill(&field_type, exprs_ident, &field_ident, root_ident)
+
+
+
+ 183 +
+
+ 298 +
+
+
        })
+
+
+
+ 184 +
+
+ 126 +
+
+
        .collect();
+
+
+
+ 185 +
+
+ 126 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/src/utils/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/src/utils/index.html new file mode 100644 index 0000000000..635a3dd46e --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/src/utils/index.html @@ -0,0 +1,98 @@ + + + + + Grcov report - crates/uniplate_derive/src/utils + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
generate.rs + + 96.38% + + + 96.38% + + 133 / 138 + 50%18 / 36
parse.rs + + 73.42% + + + 73.42% + + 58 / 79 + 50%10 / 20
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/src/utils/parse.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/src/utils/parse.rs.html new file mode 100644 index 0000000000..905107fc68 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/src/utils/parse.rs.html @@ -0,0 +1,2169 @@ + + + + + Grcov report - parse.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use proc_macro2::{Ident, Span};
+
+
+
+ 2 +
+
+ +
+
+
use syn::spanned::Spanned;
+
+
+
+ 3 +
+
+ +
+
+
use syn::{Expr, GenericArgument, PathArguments, PathSegment, Type};
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ +
+
+
/// Represents an error produced during parsing a type argument (e.g. `::<T>`)
+
+
+
+ 6 +
+
+ +
+
+
pub enum ParseTypeArgumentError {
+
+
+
+ 7 +
+
+ +
+
+
    NoTypeArguments,
+
+
+
+ 8 +
+
+ +
+
+
    EmptyTypeArguments,
+
+
+
+ 9 +
+
+ +
+
+
    MultipleTypeArguments,
+
+
+
+ 10 +
+
+ +
+
+
    TypeArgumentNotAType,
+
+
+
+ 11 +
+
+ +
+
+
    TypeArgumentValueNotPath,
+
+
+
+ 12 +
+
+ +
+
+
    TypeArgumentEmptyPath,
+
+
+
+ 13 +
+
+ +
+
+
}
+
+
+
+ 14 +
+
+ +
+
+

+            
+
+
+ 15 +
+
+ +
+
+
/// Represents a field in a tree-like structure. Used for deriving the uniplate implementation.
+
+
+
+ 16 +
+
+ +
+
+
#[derive(Debug)]
+
+
+
+ 17 +
+
+ +
+
+
pub enum UniplateField {
+
+
+
+ 18 +
+
+ +
+
+
    /// Any other valid identifier
+
+
+
+ 19 +
+
+ +
+
+
    Identifier(Ident),
+
+
+
+ 20 +
+
+ +
+
+
    /// A field consisting of a Box<T>
+
+
+
+ 21 +
+
+ +
+
+
    Box(Span, Box<UniplateField>),
+
+
+
+ 22 +
+
+ +
+
+
    /// A field consisting of a Vec<T>
+
+
+
+ 23 +
+
+ +
+
+
    Vector(Span, Box<UniplateField>),
+
+
+
+ 24 +
+
+ +
+
+
    /// A tuple of multiple fields (e.g. `(Box<T>, i32)`)
+
+
+
+ 25 +
+
+ +
+
+
    Tuple(Span, Vec<UniplateField>),
+
+
+
+ 26 +
+
+ +
+
+
    /// An array field. ToDo: currently not supported.
+
+
+
+ 27 +
+
+ +
+
+
    Array(Span, Box<UniplateField>, Expr),
+
+
+
+ 28 +
+
+ +
+
+
    /// A field that could not be parsed
+
+
+
+ 29 +
+
+ +
+
+
    Unknown(Span),
+
+
+
+ 30 +
+
+ +
+
+
}
+
+
+
+ 31 +
+
+ +
+
+

+            
+
+
+ 32 +
+
+ +
+
+
impl UniplateField {
+
+
+
+ 33 +
+
+ +
+
+
    /// Get the span corresponding to this field
+
+
+
+ 34 +
+
+ 54 +
+
+
    pub fn span(&self) -> Span {
+
+
+
+ 35 +
+
+ 54 +
+
+
        match self {
+
+
+
+ 36 +
+
+ 53 +
+
+
            UniplateField::Identifier(idnt) => idnt.span(),
+
+
+
+ 37 +
+
+ +
+
+
            UniplateField::Box(spn, _) => *spn,
+
+
+
+ 38 +
+
+ 1 +
+
+
            UniplateField::Vector(spn, _) => *spn,
+
+
+
+ 39 +
+
+ +
+
+
            UniplateField::Tuple(spn, _) => *spn,
+
+
+
+ 40 +
+
+ +
+
+
            UniplateField::Array(spn, _, _) => *spn,
+
+
+
+ 41 +
+
+ +
+
+
            UniplateField::Unknown(spn) => *spn,
+
+
+
+ 42 +
+
+ +
+
+
        }
+
+
+
+ 43 +
+
+ 54 +
+
+
    }
+
+
+
+ 44 +
+
+ +
+
+
}
+
+
+
+ 45 +
+
+ +
+
+

+            
+
+
+ 46 +
+
+ +
+
+
/// Parse a type argument from a path segment (e.g. `T` from `Box<T>`)
+
+
+
+ 47 +
+
+ 354 +
+
+
fn parse_type_argument(seg_args: &PathArguments) -> Result<&PathSegment, ParseTypeArgumentError> {
+
+
+
+ 48 +
+
+ 354 +
+
+
    match seg_args {
+
+
+
+ 49 +
+
+ 354 +
+
+
        PathArguments::AngleBracketed(type_args) => {
+
+
+
+ 50 +
+
+ 354 +
+
+
            if type_args.args.len() > 1 {
+
+
+
+ 51 +
+
+ +
+
+
                // ToDo: discuss - can and should we support multiple type arguments?
+
+
+
+ 52 +
+
+ +
+
+
                return Err(ParseTypeArgumentError::MultipleTypeArguments);
+
+
+
+ 53 +
+
+ 354 +
+
+
            }
+
+
+
+ 54 +
+
+ 354 +
+
+

+            
+
+
+ 55 +
+
+ 354 +
+
+
            match type_args.args.last() {
+
+
+
+ 56 +
+
+ +
+
+
                None => Err(ParseTypeArgumentError::EmptyTypeArguments),
+
+
+
+ 57 +
+
+ 354 +
+
+
                Some(arg) => match arg {
+
+
+
+ 58 +
+
+ 354 +
+
+
                    GenericArgument::Type(tp) => match tp {
+
+
+
+ 59 +
+
+ 354 +
+
+
                        Type::Path(pth) => match pth.path.segments.last() {
+
+
+
+ 60 +
+
+ 354 +
+
+
                            Some(seg) => Ok(seg),
+
+
+
+ 61 +
+
+ +
+
+
                            None => Err(ParseTypeArgumentError::TypeArgumentEmptyPath),
+
+
+
+ 62 +
+
+ +
+
+
                        },
+
+
+
+ 63 +
+
+ +
+
+
                        _ => Err(ParseTypeArgumentError::TypeArgumentValueNotPath),
+
+
+
+ 64 +
+
+ +
+
+
                    },
+
+
+
+ 65 +
+
+ +
+
+
                    _ => Err(ParseTypeArgumentError::TypeArgumentNotAType),
+
+
+
+ 66 +
+
+ +
+
+
                },
+
+
+
+ 67 +
+
+ +
+
+
            }
+
+
+
+ 68 +
+
+ +
+
+
        }
+
+
+
+ 69 +
+
+ +
+
+
        _ => Err(ParseTypeArgumentError::NoTypeArguments),
+
+
+
+ 70 +
+
+ +
+
+
    }
+
+
+
+ 71 +
+
+ 354 +
+
+
}
+
+
+
+ 72 +
+
+ +
+
+

+            
+
+
+ 73 +
+
+ +
+
+
/// Parse a field type into a `UniplateField`
+
+
+
+ 74 +
+
+ 608 +
+
+
pub fn parse_field_type(field_type: &Type) -> UniplateField {
+
+
+
+ 75 +
+
+ 608 +
+
+
    /// Helper function to parse a path segment into a `UniplateField`
+
+
+
+ 76 +
+
+ 956 +
+
+
    fn parse_type(seg: &PathSegment) -> UniplateField {
+
+
+
+ 77 +
+
+ 956 +
+
+
        let ident = &seg.ident;
+
+
+
+ 78 +
+
+ 956 +
+
+
        let span = ident.span();
+
+
+
+ 79 +
+
+ 956 +
+
+
        let args = &seg.arguments;
+
+
+
+ 80 +
+
+ 956 +
+
+

+            
+
+
+ 81 +
+
+ 956 +
+
+
        let box_ident = &Ident::new("Box", span);
+
+
+
+ 82 +
+
+ 956 +
+
+
        let vec_ident = &Ident::new("Vec", span); // ToDo: support other collection types
+
+
+
+ 83 +
+
+ 956 +
+
+

+            
+
+
+ 84 +
+
+ 956 +
+
+
        if ident.eq(box_ident) {
+
+
+
+ 85 +
+
+ 608 +
+
+
            match parse_type_argument(args) {
+
+
+
+ 86 +
+
+ 608 +
+
+
                Ok(inner_seg) => UniplateField::Box(seg.span(), Box::new(parse_type(inner_seg))),
+
+
+
+ 87 +
+
+ 608 +
+
+
                Err(_) => UniplateField::Unknown(ident.span()),
+
+
+
+ 88 +
+
+ 608 +
+
+
            }
+
+
+
+ 89 +
+
+ 710 +
+
+
        } else if ident.eq(vec_ident) {
+
+
+
+ 90 +
+
+ 608 +
+
+
            match parse_type_argument(args) {
+
+
+
+ 91 +
+
+ 608 +
+
+
                Ok(inner_seg) => UniplateField::Vector(seg.span(), Box::new(parse_type(inner_seg))),
+
+
+
+ 92 +
+
+ 608 +
+
+
                Err(_) => UniplateField::Unknown(ident.span()),
+
+
+
+ 93 +
+
+ 608 +
+
+
            }
+
+
+
+ 94 +
+
+ 608 +
+
+
        } else {
+
+
+
+ 95 +
+
+ 608 +
+
+
            UniplateField::Identifier(ident.clone())
+
+
+
+ 96 +
+
+ 608 +
+
+
        }
+
+
+
+ 97 +
+
+ 956 +
+
+
    }
+
+
+
+ 98 +
+
+ 608 +
+
+

+            
+
+
+ 99 +
+
+ 608 +
+
+
    match field_type {
+
+
+
+ 100 +
+
+ 602 +
+
+
        Type::Path(path) => match path.path.segments.last() {
+
+
+
+ 101 +
+
+ +
+
+
            None => UniplateField::Unknown(path.span()),
+
+
+
+ 102 +
+
+ 602 +
+
+
            Some(seg) => parse_type(seg),
+
+
+
+ 103 +
+
+ +
+
+
        },
+
+
+
+ 104 +
+
+ 6 +
+
+
        Type::Tuple(tpl) => {
+
+
+
+ 105 +
+
+ 6 +
+
+
            UniplateField::Tuple(tpl.span(), tpl.elems.iter().map(parse_field_type).collect())
+
+
+
+ 106 +
+
+ +
+
+
        }
+
+
+
+ 107 +
+
+ +
+
+
        Type::Array(arr) => UniplateField::Array(
+
+
+
+ 108 +
+
+ +
+
+
            arr.span(),
+
+
+
+ 109 +
+
+ +
+
+
            Box::new(parse_field_type(arr.elem.as_ref())),
+
+
+
+ 110 +
+
+ +
+
+
            arr.len.clone(),
+
+
+
+ 111 +
+
+ +
+
+
        ),
+
+
+
+ 112 +
+
+ +
+
+
        _ => UniplateField::Unknown(field_type.span()), // ToDo discuss - Can we support any of: BareFn, Group, ImplTrait, Infer, Macro, Never, Paren, Ptr, Reference, TraitObject, Verbatim
+
+
+
+ 113 +
+
+ +
+
+
    }
+
+
+
+ 114 +
+
+ 608 +
+
+
}
+
+
+
+ 115 +
+
+ +
+
+

+            
+
+
+ 116 +
+
+ +
+
+
/// Check if a field type is equal to a given identifier. Used to check if a field is an instance of the root type.
+
+
+
+ 117 +
+
+ 1330 +
+
+
pub fn check_field_type(ft: &UniplateField, root_ident: &Ident) -> bool {
+
+
+
+ 118 +
+
+ 1330 +
+
+
    match ft {
+
+
+
+ 119 +
+
+ 962 +
+
+
        UniplateField::Identifier(ident) => ident.eq(root_ident),
+
+
+
+ 120 +
+
+ 252 +
+
+
        UniplateField::Box(_, subfield) => check_field_type(subfield.as_ref(), root_ident),
+
+
+
+ 121 +
+
+ 110 +
+
+
        UniplateField::Vector(_, subfield) => check_field_type(subfield.as_ref(), root_ident),
+
+
+
+ 122 +
+
+ 6 +
+
+
        UniplateField::Tuple(_, subfields) => {
+
+
+
+ 123 +
+
+ 6 +
+
+
            for sft in subfields {
+
+
+
+ 124 +
+
+ 6 +
+
+
                if check_field_type(sft, root_ident) {
+
+
+
+ 125 +
+
+ 6 +
+
+
                    return true;
+
+
+
+ 126 +
+
+ +
+
+
                }
+
+
+
+ 127 +
+
+ +
+
+
            }
+
+
+
+ 128 +
+
+ +
+
+
            false
+
+
+
+ 129 +
+
+ +
+
+
        }
+
+
+
+ 130 +
+
+ +
+
+
        UniplateField::Array(_, arr_type, _) => check_field_type(arr_type.as_ref(), root_ident),
+
+
+
+ 131 +
+
+ +
+
+
        UniplateField::Unknown(_) => false,
+
+
+
+ 132 +
+
+ +
+
+
    }
+
+
+
+ 133 +
+
+ 1330 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/tests/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/tests/index.html new file mode 100644 index 0000000000..c72a96572f --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/tests/index.html @@ -0,0 +1,74 @@ + + + + + Grcov report - crates/uniplate_derive/tests + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
macro_tests.rs + + 100% + + + 100% + + 188 / 188 + 100%36 / 36
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/tests/macro_tests.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/tests/macro_tests.rs.html new file mode 100644 index 0000000000..c748637343 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/crates/uniplate_derive/tests/macro_tests.rs.html @@ -0,0 +1,3945 @@ + + + + + Grcov report - macro_tests.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use uniplate::uniplate::Uniplate;
+
+
+
+ 2 +
+
+ +
+
+
use uniplate_derive::Uniplate;
+
+
+
+ 3 +
+
+ +
+
+

+            
+
+
+ 4 +
+
+ 47 +
+
+
#[derive(Clone, Debug, PartialEq, Eq, Uniplate)]
+
+
+
+ 5 +
+
+ +
+
+
enum TestEnum {
+
+
+
+ 6 +
+
+ +
+
+
    A(i32),
+
+
+
+ 7 +
+
+ +
+
+
    B(Box<TestEnum>),
+
+
+
+ 8 +
+
+ +
+
+
    C(Vec<TestEnum>),
+
+
+
+ 9 +
+
+ +
+
+
    D(bool, Box<TestEnum>),
+
+
+
+ 10 +
+
+ +
+
+
    E(Box<TestEnum>, Box<TestEnum>),
+
+
+
+ 11 +
+
+ +
+
+
    F((Box<TestEnum>, Box<TestEnum>)),
+
+
+
+ 12 +
+
+ +
+
+
    G((Box<TestEnum>, (Box<TestEnum>, i32))),
+
+
+
+ 13 +
+
+ +
+
+
    H(Vec<Vec<TestEnum>>),
+
+
+
+ 14 +
+
+ +
+
+
    I(Vec<TestEnum>, i32, Vec<TestEnum>),
+
+
+
+ 15 +
+
+ +
+
+
}
+
+
+
+ 16 +
+
+ +
+
+

+            
+
+
+ 17 +
+
+ +
+
+
#[test]
+
+
+
+ 18 +
+
+ 1 +
+
+
fn increase_number_of_children() {
+
+
+
+ 19 +
+
+ 1 +
+
+
    let c = TestEnum::C(vec![TestEnum::A(42)]);
+
+
+
+ 20 +
+
+ 1 +
+
+
    let context = c.uniplate().1;
+
+
+
+ 21 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 22 +
+
+ 1 +
+
+
        context(vec![TestEnum::A(42), TestEnum::A(42)]),
+
+
+
+ 23 +
+
+ 1 +
+
+
        Err(uniplate::uniplate::UniplateError::WrongNumberOfChildren(
+
+
+
+ 24 +
+
+ 1 +
+
+
            1, 2
+
+
+
+ 25 +
+
+ 1 +
+
+
        ))
+
+
+
+ 26 +
+
+ 1 +
+
+
    );
+
+
+
+ 27 +
+
+ 1 +
+
+
}
+
+
+
+ 28 +
+
+ +
+
+

+            
+
+
+ 29 +
+
+ +
+
+
#[test]
+
+
+
+ 30 +
+
+ 1 +
+
+
fn decrease_number_of_children() {
+
+
+
+ 31 +
+
+ 1 +
+
+
    let c = TestEnum::C(vec![TestEnum::A(42)]);
+
+
+
+ 32 +
+
+ 1 +
+
+
    let context = c.uniplate().1;
+
+
+
+ 33 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 34 +
+
+ 1 +
+
+
        context(vec![]),
+
+
+
+ 35 +
+
+ 1 +
+
+
        Err(uniplate::uniplate::UniplateError::WrongNumberOfChildren(
+
+
+
+ 36 +
+
+ 1 +
+
+
            1, 0
+
+
+
+ 37 +
+
+ 1 +
+
+
        ))
+
+
+
+ 38 +
+
+ 1 +
+
+
    );
+
+
+
+ 39 +
+
+ 1 +
+
+
}
+
+
+
+ 40 +
+
+ +
+
+

+            
+
+
+ 41 +
+
+ +
+
+
#[test]
+
+
+
+ 42 +
+
+ 1 +
+
+
fn derive_context_empty() {
+
+
+
+ 43 +
+
+ 1 +
+
+
    let a = TestEnum::A(42);
+
+
+
+ 44 +
+
+ 1 +
+
+
    let context = a.uniplate().1;
+
+
+
+ 45 +
+
+ 1 +
+
+
    assert_eq!(context(vec![]).unwrap(), a)
+
+
+
+ 46 +
+
+ 1 +
+
+
}
+
+
+
+ 47 +
+
+ +
+
+

+            
+
+
+ 48 +
+
+ +
+
+
#[test]
+
+
+
+ 49 +
+
+ 1 +
+
+
fn derive_context_box() {
+
+
+
+ 50 +
+
+ 1 +
+
+
    let a = TestEnum::A(42);
+
+
+
+ 51 +
+
+ 1 +
+
+
    let b = TestEnum::B(Box::new(a.clone()));
+
+
+
+ 52 +
+
+ 1 +
+
+
    let context = b.uniplate().1;
+
+
+
+ 53 +
+
+ 1 +
+
+
    assert_eq!(context(vec![a.clone()]).unwrap(), b);
+
+
+
+ 54 +
+
+ 1 +
+
+
}
+
+
+
+ 55 +
+
+ +
+
+

+            
+
+
+ 56 +
+
+ +
+
+
#[test]
+
+
+
+ 57 +
+
+ 1 +
+
+
fn derive_context_vec() {
+
+
+
+ 58 +
+
+ 1 +
+
+
    let a = TestEnum::A(1);
+
+
+
+ 59 +
+
+ 1 +
+
+
    let b = TestEnum::B(Box::new(TestEnum::A(2)));
+
+
+
+ 60 +
+
+ 1 +
+
+
    let c = TestEnum::C(vec![a.clone(), b.clone()]);
+
+
+
+ 61 +
+
+ 1 +
+
+
    let context = c.uniplate().1;
+
+
+
+ 62 +
+
+ 1 +
+
+
    assert_eq!(context(vec![a.clone(), b.clone()]).unwrap(), c);
+
+
+
+ 63 +
+
+ 1 +
+
+
}
+
+
+
+ 64 +
+
+ +
+
+

+            
+
+
+ 65 +
+
+ +
+
+
#[test]
+
+
+
+ 66 +
+
+ 1 +
+
+
fn derive_context_two() {
+
+
+
+ 67 +
+
+ 1 +
+
+
    let d = TestEnum::D(true, Box::new(TestEnum::A(42)));
+
+
+
+ 68 +
+
+ 1 +
+
+
    let context = d.uniplate().1;
+
+
+
+ 69 +
+
+ 1 +
+
+
    assert_eq!(context(vec![TestEnum::A(42)]).unwrap(), d);
+
+
+
+ 70 +
+
+ 1 +
+
+
}
+
+
+
+ 71 +
+
+ +
+
+

+            
+
+
+ 72 +
+
+ +
+
+
#[test]
+
+
+
+ 73 +
+
+ 1 +
+
+
fn derive_context_tuple() {
+
+
+
+ 74 +
+
+ 1 +
+
+
    let e = TestEnum::F((Box::new(TestEnum::A(1)), Box::new(TestEnum::A(2))));
+
+
+
+ 75 +
+
+ 1 +
+
+
    let context = e.uniplate().1;
+
+
+
+ 76 +
+
+ 1 +
+
+
    assert_eq!(context(vec![TestEnum::A(1), TestEnum::A(2)]).unwrap(), e);
+
+
+
+ 77 +
+
+ 1 +
+
+
}
+
+
+
+ 78 +
+
+ +
+
+

+            
+
+
+ 79 +
+
+ +
+
+
#[test]
+
+
+
+ 80 +
+
+ 1 +
+
+
fn derive_context_different_variants() {
+
+
+
+ 81 +
+
+ 1 +
+
+
    let f = TestEnum::E(
+
+
+
+ 82 +
+
+ 1 +
+
+
        Box::new(TestEnum::A(1)),
+
+
+
+ 83 +
+
+ 1 +
+
+
        Box::new(TestEnum::B(Box::new(TestEnum::A(2)))),
+
+
+
+ 84 +
+
+ 1 +
+
+
    );
+
+
+
+ 85 +
+
+ 1 +
+
+
    let context = f.uniplate().1;
+
+
+
+ 86 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 87 +
+
+ 1 +
+
+
        context(vec![TestEnum::A(1), TestEnum::B(Box::new(TestEnum::A(2)))]).unwrap(),
+
+
+
+ 88 +
+
+ 1 +
+
+
        f
+
+
+
+ 89 +
+
+ 1 +
+
+
    );
+
+
+
+ 90 +
+
+ 1 +
+
+
}
+
+
+
+ 91 +
+
+ +
+
+

+            
+
+
+ 92 +
+
+ +
+
+
#[test]
+
+
+
+ 93 +
+
+ 1 +
+
+
fn derive_context_nested_tuples() {
+
+
+
+ 94 +
+
+ 1 +
+
+
    let g = TestEnum::G((Box::new(TestEnum::A(1)), (Box::new(TestEnum::A(2)), 42)));
+
+
+
+ 95 +
+
+ 1 +
+
+
    let context = g.uniplate().1;
+
+
+
+ 96 +
+
+ 1 +
+
+
    assert_eq!(context(vec![TestEnum::A(1), TestEnum::A(2)]).unwrap(), g);
+
+
+
+ 97 +
+
+ 1 +
+
+
}
+
+
+
+ 98 +
+
+ +
+
+

+            
+
+
+ 99 +
+
+ +
+
+
#[test]
+
+
+
+ 100 +
+
+ 1 +
+
+
fn derive_context_nested_vectors() {
+
+
+
+ 101 +
+
+ 1 +
+
+
    let h = TestEnum::H(vec![
+
+
+
+ 102 +
+
+ 1 +
+
+
        vec![TestEnum::A(1), TestEnum::A(2)],
+
+
+
+ 103 +
+
+ 1 +
+
+
        vec![TestEnum::A(3), TestEnum::A(4)],
+
+
+
+ 104 +
+
+ 1 +
+
+
    ]);
+
+
+
+ 105 +
+
+ 1 +
+
+
    let context = h.uniplate().1;
+
+
+
+ 106 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 107 +
+
+ 1 +
+
+
        context(vec![
+
+
+
+ 108 +
+
+ 1 +
+
+
            TestEnum::A(1),
+
+
+
+ 109 +
+
+ 1 +
+
+
            TestEnum::A(2),
+
+
+
+ 110 +
+
+ 1 +
+
+
            TestEnum::A(3),
+
+
+
+ 111 +
+
+ 1 +
+
+
            TestEnum::A(4)
+
+
+
+ 112 +
+
+ 1 +
+
+
        ])
+
+
+
+ 113 +
+
+ 1 +
+
+
        .unwrap(),
+
+
+
+ 114 +
+
+ 1 +
+
+
        h
+
+
+
+ 115 +
+
+ 1 +
+
+
    );
+
+
+
+ 116 +
+
+ 1 +
+
+
}
+
+
+
+ 117 +
+
+ +
+
+

+            
+
+
+ 118 +
+
+ +
+
+
#[test]
+
+
+
+ 119 +
+
+ 1 +
+
+
fn derive_context_multiple_vecs() {
+
+
+
+ 120 +
+
+ 1 +
+
+
    let i = TestEnum::I(
+
+
+
+ 121 +
+
+ 1 +
+
+
        vec![TestEnum::A(1), TestEnum::A(2)],
+
+
+
+ 122 +
+
+ 1 +
+
+
        42,
+
+
+
+ 123 +
+
+ 1 +
+
+
        vec![TestEnum::A(3), TestEnum::A(4)],
+
+
+
+ 124 +
+
+ 1 +
+
+
    );
+
+
+
+ 125 +
+
+ 1 +
+
+
    let context = i.uniplate().1;
+
+
+
+ 126 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 127 +
+
+ 1 +
+
+
        context(vec![
+
+
+
+ 128 +
+
+ 1 +
+
+
            TestEnum::A(1),
+
+
+
+ 129 +
+
+ 1 +
+
+
            TestEnum::A(2),
+
+
+
+ 130 +
+
+ 1 +
+
+
            TestEnum::A(3),
+
+
+
+ 131 +
+
+ 1 +
+
+
            TestEnum::A(4)
+
+
+
+ 132 +
+
+ 1 +
+
+
        ])
+
+
+
+ 133 +
+
+ 1 +
+
+
        .unwrap(),
+
+
+
+ 134 +
+
+ 1 +
+
+
        i
+
+
+
+ 135 +
+
+ 1 +
+
+
    );
+
+
+
+ 136 +
+
+ 1 +
+
+
}
+
+
+
+ 137 +
+
+ +
+
+

+            
+
+
+ 138 +
+
+ +
+
+
#[test]
+
+
+
+ 139 +
+
+ 1 +
+
+
fn box_change_child() {
+
+
+
+ 140 +
+
+ 1 +
+
+
    let b = TestEnum::B(Box::new(TestEnum::A(1)));
+
+
+
+ 141 +
+
+ 1 +
+
+
    let context = b.uniplate().1;
+
+
+
+ 142 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 143 +
+
+ 1 +
+
+
        context(vec![TestEnum::C(vec![TestEnum::A(41), TestEnum::A(42)])]).unwrap(),
+
+
+
+ 144 +
+
+ 1 +
+
+
        TestEnum::B(Box::new(TestEnum::C(vec![
+
+
+
+ 145 +
+
+ 1 +
+
+
            TestEnum::A(41),
+
+
+
+ 146 +
+
+ 1 +
+
+
            TestEnum::A(42)
+
+
+
+ 147 +
+
+ 1 +
+
+
        ])))
+
+
+
+ 148 +
+
+ 1 +
+
+
    );
+
+
+
+ 149 +
+
+ 1 +
+
+
}
+
+
+
+ 150 +
+
+ +
+
+

+            
+
+
+ 151 +
+
+ +
+
+
#[test]
+
+
+
+ 152 +
+
+ 1 +
+
+
fn derive_children_empty() {
+
+
+
+ 153 +
+
+ 1 +
+
+
    let a = TestEnum::A(42);
+
+
+
+ 154 +
+
+ 1 +
+
+
    let children = a.uniplate().0;
+
+
+
+ 155 +
+
+ 1 +
+
+
    assert_eq!(children, vec![]);
+
+
+
+ 156 +
+
+ 1 +
+
+
}
+
+
+
+ 157 +
+
+ +
+
+

+            
+
+
+ 158 +
+
+ +
+
+
#[test]
+
+
+
+ 159 +
+
+ 1 +
+
+
fn derive_children_box() {
+
+
+
+ 160 +
+
+ 1 +
+
+
    let b = TestEnum::B(Box::new(TestEnum::A(42)));
+
+
+
+ 161 +
+
+ 1 +
+
+
    let children = b.uniplate().0;
+
+
+
+ 162 +
+
+ 1 +
+
+
    assert_eq!(children, vec![TestEnum::A(42)]);
+
+
+
+ 163 +
+
+ 1 +
+
+
}
+
+
+
+ 164 +
+
+ +
+
+

+            
+
+
+ 165 +
+
+ +
+
+
#[test]
+
+
+
+ 166 +
+
+ 1 +
+
+
fn derive_children_vec() {
+
+
+
+ 167 +
+
+ 1 +
+
+
    let c = TestEnum::C(vec![TestEnum::A(1), TestEnum::B(Box::new(TestEnum::A(2)))]);
+
+
+
+ 168 +
+
+ 1 +
+
+
    let children = c.uniplate().0;
+
+
+
+ 169 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 170 +
+
+ 1 +
+
+
        children,
+
+
+
+ 171 +
+
+ 1 +
+
+
        vec![TestEnum::A(1), TestEnum::B(Box::new(TestEnum::A(2))),]
+
+
+
+ 172 +
+
+ 1 +
+
+
    );
+
+
+
+ 173 +
+
+ 1 +
+
+
}
+
+
+
+ 174 +
+
+ +
+
+

+            
+
+
+ 175 +
+
+ +
+
+
#[test]
+
+
+
+ 176 +
+
+ 1 +
+
+
fn derive_children_two() {
+
+
+
+ 177 +
+
+ 1 +
+
+
    let d = TestEnum::D(true, Box::new(TestEnum::A(42)));
+
+
+
+ 178 +
+
+ 1 +
+
+
    let children = d.uniplate().0;
+
+
+
+ 179 +
+
+ 1 +
+
+
    assert_eq!(children, vec![TestEnum::A(42)]);
+
+
+
+ 180 +
+
+ 1 +
+
+
}
+
+
+
+ 181 +
+
+ +
+
+

+            
+
+
+ 182 +
+
+ +
+
+
#[test]
+
+
+
+ 183 +
+
+ 1 +
+
+
fn derive_children_tuple() {
+
+
+
+ 184 +
+
+ 1 +
+
+
    let e = TestEnum::F((Box::new(TestEnum::A(1)), Box::new(TestEnum::A(2))));
+
+
+
+ 185 +
+
+ 1 +
+
+
    let children = e.uniplate().0;
+
+
+
+ 186 +
+
+ 1 +
+
+
    assert_eq!(children, vec![TestEnum::A(1), TestEnum::A(2),]);
+
+
+
+ 187 +
+
+ 1 +
+
+
}
+
+
+
+ 188 +
+
+ +
+
+

+            
+
+
+ 189 +
+
+ +
+
+
#[test]
+
+
+
+ 190 +
+
+ 1 +
+
+
fn derive_children_different_variants() {
+
+
+
+ 191 +
+
+ 1 +
+
+
    let f = TestEnum::E(
+
+
+
+ 192 +
+
+ 1 +
+
+
        Box::new(TestEnum::A(1)),
+
+
+
+ 193 +
+
+ 1 +
+
+
        Box::new(TestEnum::B(Box::new(TestEnum::A(2)))),
+
+
+
+ 194 +
+
+ 1 +
+
+
    );
+
+
+
+ 195 +
+
+ 1 +
+
+
    let children = f.uniplate().0;
+
+
+
+ 196 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 197 +
+
+ 1 +
+
+
        children,
+
+
+
+ 198 +
+
+ 1 +
+
+
        vec![TestEnum::A(1), TestEnum::B(Box::new(TestEnum::A(2)))]
+
+
+
+ 199 +
+
+ 1 +
+
+
    );
+
+
+
+ 200 +
+
+ 1 +
+
+
}
+
+
+
+ 201 +
+
+ +
+
+

+            
+
+
+ 202 +
+
+ +
+
+
#[test]
+
+
+
+ 203 +
+
+ 1 +
+
+
fn derive_children_nested_tuples() {
+
+
+
+ 204 +
+
+ 1 +
+
+
    let g = TestEnum::G((Box::new(TestEnum::A(1)), (Box::new(TestEnum::A(2)), 42)));
+
+
+
+ 205 +
+
+ 1 +
+
+
    let children = g.uniplate().0;
+
+
+
+ 206 +
+
+ 1 +
+
+
    assert_eq!(children, vec![TestEnum::A(1), TestEnum::A(2)])
+
+
+
+ 207 +
+
+ 1 +
+
+
}
+
+
+
+ 208 +
+
+ +
+
+

+            
+
+
+ 209 +
+
+ +
+
+
#[test]
+
+
+
+ 210 +
+
+ 1 +
+
+
fn derive_children_nested_vectors() {
+
+
+
+ 211 +
+
+ 1 +
+
+
    let h = TestEnum::H(vec![
+
+
+
+ 212 +
+
+ 1 +
+
+
        vec![TestEnum::A(1), TestEnum::A(2)],
+
+
+
+ 213 +
+
+ 1 +
+
+
        vec![TestEnum::A(3), TestEnum::A(4)],
+
+
+
+ 214 +
+
+ 1 +
+
+
    ]);
+
+
+
+ 215 +
+
+ 1 +
+
+
    let children = h.uniplate().0;
+
+
+
+ 216 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 217 +
+
+ 1 +
+
+
        children,
+
+
+
+ 218 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 219 +
+
+ 1 +
+
+
            TestEnum::A(1),
+
+
+
+ 220 +
+
+ 1 +
+
+
            TestEnum::A(2),
+
+
+
+ 221 +
+
+ 1 +
+
+
            TestEnum::A(3),
+
+
+
+ 222 +
+
+ 1 +
+
+
            TestEnum::A(4)
+
+
+
+ 223 +
+
+ 1 +
+
+
        ]
+
+
+
+ 224 +
+
+ 1 +
+
+
    )
+
+
+
+ 225 +
+
+ 1 +
+
+
}
+
+
+
+ 226 +
+
+ +
+
+

+            
+
+
+ 227 +
+
+ +
+
+
#[test]
+
+
+
+ 228 +
+
+ 1 +
+
+
fn derive_children_multiple_vecs() {
+
+
+
+ 229 +
+
+ 1 +
+
+
    let i = TestEnum::I(
+
+
+
+ 230 +
+
+ 1 +
+
+
        vec![TestEnum::A(1), TestEnum::A(2)],
+
+
+
+ 231 +
+
+ 1 +
+
+
        42,
+
+
+
+ 232 +
+
+ 1 +
+
+
        vec![TestEnum::A(3), TestEnum::A(4)],
+
+
+
+ 233 +
+
+ 1 +
+
+
    );
+
+
+
+ 234 +
+
+ 1 +
+
+
    let children = i.uniplate().0;
+
+
+
+ 235 +
+
+ 1 +
+
+
    assert_eq!(
+
+
+
+ 236 +
+
+ 1 +
+
+
        children,
+
+
+
+ 237 +
+
+ 1 +
+
+
        vec![
+
+
+
+ 238 +
+
+ 1 +
+
+
            TestEnum::A(1),
+
+
+
+ 239 +
+
+ 1 +
+
+
            TestEnum::A(2),
+
+
+
+ 240 +
+
+ 1 +
+
+
            TestEnum::A(3),
+
+
+
+ 241 +
+
+ 1 +
+
+
            TestEnum::A(4)
+
+
+
+ 242 +
+
+ 1 +
+
+
        ]
+
+
+
+ 243 +
+
+ 1 +
+
+
    );
+
+
+
+ 244 +
+
+ 1 +
+
+
}
+
+
+
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/doc-coverage.json b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/doc-coverage.json new file mode 100644 index 0000000000..63bf3ae093 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/doc-coverage.json @@ -0,0 +1,9 @@ +{"crates/enum_compatability_macro/src/lib.rs":{"total":2,"with_docs":2,"total_examples":2,"with_examples":1}} +{"crates/conjure_macros/src/lib.rs":{"total":3,"with_docs":2,"total_examples":3,"with_examples":1}} +{"crates/uniplate_derive/src/lib.rs":{"total":2,"with_docs":1,"total_examples":2,"with_examples":1}} +{"conjure_oxide/src/find_conjure.rs":{"total":2,"with_docs":1,"total_examples":2,"with_examples":0},"conjure_oxide/src/lib.rs":{"total":1,"with_docs":0,"total_examples":1,"with_examples":0},"conjure_oxide/src/utils/conjure.rs":{"total":7,"with_docs":0,"total_examples":5,"with_examples":0},"conjure_oxide/src/utils/json.rs":{"total":3,"with_docs":2,"total_examples":3,"with_examples":0},"conjure_oxide/src/utils/misc.rs":{"total":2,"with_docs":0,"total_examples":2,"with_examples":0},"conjure_oxide/src/utils/mod.rs":{"total":1,"with_docs":0,"total_examples":1,"with_examples":0},"conjure_oxide/src/utils/testing.rs":{"total":9,"with_docs":0,"total_examples":9,"with_examples":0}} +{"solvers/kissat/src/lib.rs":{"total":1,"with_docs":0,"total_examples":1,"with_examples":0}} +{"/home/runner/work/conjure-oxide/conjure-oxide/target/debug/build/chuffed_rs-deaded5605d26364/out/chuffed_bindings.rs":{"total":207,"with_docs":0,"total_examples":104,"with_examples":0},"solvers/chuffed/src/lib.rs":{"total":10,"with_docs":0,"total_examples":10,"with_examples":0}} +{"crates/uniplate/src/biplate.rs":{"total":16,"with_docs":9,"total_examples":16,"with_examples":0},"crates/uniplate/src/lib.rs":{"total":1,"with_docs":1,"total_examples":1,"with_examples":1},"crates/uniplate/src/uniplate.rs":{"total":13,"with_docs":9,"total_examples":12,"with_examples":0}} +{"solvers/minion/src/ast.rs":{"total":98,"with_docs":11,"total_examples":12,"with_examples":0},"solvers/minion/src/error.rs":{"total":8,"with_docs":8,"total_examples":3,"with_examples":0},"solvers/minion/src/lib.rs":{"total":1,"with_docs":1,"total_examples":1,"with_examples":1}} +{"crates/conjure_core/src/ast/mod.rs":{"total":1,"with_docs":0,"total_examples":1,"with_examples":0},"crates/conjure_core/src/context.rs":{"total":10,"with_docs":0,"total_examples":4,"with_examples":0},"crates/conjure_core/src/error.rs":{"total":7,"with_docs":1,"total_examples":2,"with_examples":0},"crates/conjure_core/src/lib.rs":{"total":1,"with_docs":0,"total_examples":1,"with_examples":0},"crates/conjure_core/src/metadata.rs":{"total":4,"with_docs":0,"total_examples":3,"with_examples":0},"crates/conjure_core/src/model.rs":{"total":16,"with_docs":1,"total_examples":13,"with_examples":0},"crates/conjure_core/src/parse/mod.rs":{"total":1,"with_docs":0,"total_examples":1,"with_examples":0},"crates/conjure_core/src/rule_engine/mod.rs":{"total":7,"with_docs":5,"total_examples":7,"with_examples":5},"crates/conjure_core/src/rules/mod.rs":{"total":1,"with_docs":0,"total_examples":1,"with_examples":0},"crates/conjure_core/src/solver/adaptors/mod.rs":{"total":1,"with_docs":1,"total_examples":1,"with_examples":0},"crates/conjure_core/src/solver/mod.rs":{"total":42,"with_docs":14,"total_examples":24,"with_examples":1},"crates/conjure_core/src/solver/model_modifier.rs":{"total":10,"with_docs":7,"total_examples":6,"with_examples":0},"crates/conjure_core/src/solver/states.rs":{"total":11,"with_docs":7,"total_examples":6,"with_examples":0},"crates/conjure_core/src/stats/mod.rs":{"total":5,"with_docs":0,"total_examples":4,"with_examples":0}} diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/doc-coverage.txt b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/doc-coverage.txt new file mode 100644 index 0000000000..3750af6c45 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/doc-coverage.txt @@ -0,0 +1,104 @@ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| crates/uniplate_derive/src/lib.rs | 1 | 50.0% | 1 | 50.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 1 | 50.0% | 1 | 50.0% | ++-------------------------------------+------------+------------+------------+------------+ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| crates/conjure_macros/src/lib.rs | 2 | 66.7% | 1 | 33.3% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 2 | 66.7% | 1 | 33.3% | ++-------------------------------------+------------+------------+------------+------------+ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...m_compatability_macro/src/lib.rs | 2 | 100.0% | 1 | 50.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 2 | 100.0% | 1 | 50.0% | ++-------------------------------------+------------+------------+------------+------------+ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| crates/uniplate/src/biplate.rs | 9 | 56.2% | 0 | 0.0% | +| crates/uniplate/src/lib.rs | 1 | 100.0% | 1 | 100.0% | +| crates/uniplate/src/tree.rs | 0 | 0.0% | 0 | 0.0% | +| crates/uniplate/src/uniplate.rs | 9 | 69.2% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 19 | 55.9% | 1 | 3.4% | ++-------------------------------------+------------+------------+------------+------------+ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| solvers/kissat/src/lib.rs | 0 | 0.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 0 | 0.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| solvers/minion/src/ast.rs | 11 | 11.2% | 0 | 0.0% | +| solvers/minion/src/error.rs | 8 | 100.0% | 0 | 0.0% | +| solvers/minion/src/lib.rs | 1 | 100.0% | 1 | 100.0% | +| solvers/minion/src/run.rs | 2 | 100.0% | 1 | 100.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 22 | 20.2% | 2 | 11.8% | ++-------------------------------------+------------+------------+------------+------------+ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...onjure_core/src/ast/constants.rs | 0 | 0.0% | 0 | 0.0% | +| .../conjure_core/src/ast/domains.rs | 0 | 0.0% | 0 | 0.0% | +| ...jure_core/src/ast/expressions.rs | 19 | 95.0% | 0 | 0.0% | +| crates/conjure_core/src/ast/mod.rs | 0 | 0.0% | 0 | 0.0% | +| ...ure_core/src/ast/symbol_table.rs | 0 | 0.0% | 0 | 0.0% | +| ...onjure_core/src/ast/variables.rs | 0 | 0.0% | 0 | 0.0% | +| crates/conjure_core/src/context.rs | 0 | 0.0% | 0 | 0.0% | +| crates/conjure_core/src/error.rs | 1 | 14.3% | 0 | 0.0% | +| crates/conjure_core/src/lib.rs | 0 | 0.0% | 0 | 0.0% | +| crates/conjure_core/src/metadata.rs | 0 | 0.0% | 0 | 0.0% | +| crates/conjure_core/src/model.rs | 1 | 6.2% | 0 | 0.0% | +| ...core/src/parse/example_models.rs | 2 | 100.0% | 0 | 0.0% | +| ...es/conjure_core/src/parse/mod.rs | 0 | 0.0% | 0 | 0.0% | +| ...re_core/src/parse/parse_model.rs | 0 | 0.0% | 0 | 0.0% | +| ...jure_core/src/rule_engine/mod.rs | 5 | 71.4% | 5 | 71.4% | +| ...src/rule_engine/resolve_rules.rs | 3 | 100.0% | 0 | 0.0% | +| ..._core/src/rule_engine/rewrite.rs | 1 | 33.3% | 0 | 0.0% | +| ...ure_core/src/rule_engine/rule.rs | 3 | 25.0% | 0 | 0.0% | +| ...core/src/rule_engine/rule_set.rs | 4 | 100.0% | 0 | 0.0% | +| ...njure_core/src/rules/constant.rs | 1 | 100.0% | 0 | 0.0% | +| ...es/conjure_core/src/rules/mod.rs | 0 | 0.0% | 0 | 0.0% | +| ...re/src/solver/adaptors/kissat.rs | 1 | 100.0% | 0 | 0.0% | +| ...re/src/solver/adaptors/minion.rs | 1 | 100.0% | 0 | 0.0% | +| ..._core/src/solver/adaptors/mod.rs | 1 | 100.0% | 0 | 0.0% | +| ...s/conjure_core/src/solver/mod.rs | 14 | 33.3% | 1 | 4.2% | +| ...ore/src/solver/model_modifier.rs | 7 | 70.0% | 0 | 0.0% | +| ...onjure_core/src/solver/states.rs | 7 | 63.6% | 0 | 0.0% | +| ...es/conjure_core/src/stats/mod.rs | 0 | 0.0% | 0 | 0.0% | +| ...e_core/src/stats/solver_stats.rs | 3 | 37.5% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 74 | 39.4% | 6 | 8.1% | ++-------------------------------------+------------+------------+------------+------------+ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| conjure_oxide/src/find_conjure.rs | 1 | 50.0% | 0 | 0.0% | +| conjure_oxide/src/lib.rs | 0 | 0.0% | 0 | 0.0% | +| conjure_oxide/src/utils/conjure.rs | 0 | 0.0% | 0 | 0.0% | +| conjure_oxide/src/utils/json.rs | 2 | 66.7% | 0 | 0.0% | +| conjure_oxide/src/utils/misc.rs | 0 | 0.0% | 0 | 0.0% | +| conjure_oxide/src/utils/mod.rs | 0 | 0.0% | 0 | 0.0% | +| conjure_oxide/src/utils/testing.rs | 0 | 0.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 3 | 12.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ ++-------------------------------------+------------+------------+------------+------------+ +| File | Documented | Percentage | Examples | Percentage | ++-------------------------------------+------------+------------+------------+------------+ +| ...05d26364/out/chuffed_bindings.rs | 0 | 0.0% | 0 | 0.0% | +| solvers/chuffed/src/lib.rs | 0 | 0.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ +| Total | 0 | 0.0% | 0 | 0.0% | ++-------------------------------------+------------+------------+------------+------------+ diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/index.html new file mode 100644 index 0000000000..fc0b80533e --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/index.html @@ -0,0 +1,626 @@ + + + + + Grcov report - top_level + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DirectoryLine CoverageFunctions
conjure_oxide/src + + 47.92% + + + 47.92% + + 23 / 48 + 16.67%1 / 6
conjure_oxide/src/utils + + 67.86% + + + 67.86% + + 171 / 252 + 25.4%16 / 63
conjure_oxide/tests + + 95.17% + + + 95.17% + + 966 / 1015 + 95.74%45 / 47
crates/conjure_core/src + + 43.7% + + + 43.7% + + 52 / 119 + 11.11%18 / 162
crates/conjure_core/src/ast + + 27.13% + + + 27.13% + + 51 / 188 + 11.47%60 / 523
crates/conjure_core/src/parse + + 87.09% + + + 87.09% + + 263 / 302 + 28.33%17 / 60
crates/conjure_core/src/rule_engine + + 73.49% + + + 73.49% + + 280 / 381 + 24.05%38 / 158
crates/conjure_core/src/rules + + 84.01% + + + 84.01% + + 536 / 638 + 15.42%78 / 506
crates/conjure_core/src/solver + + 68.71% + + + 68.71% + + 112 / 163 + 12.4%15 / 121
crates/conjure_core/src/solver/adaptors + + 47.91% + + + 47.91% + + 206 / 430 + 12.73%21 / 165
crates/conjure_core/src/stats + + 75% + + + 75% + + 9 / 12 + 22.22%2 / 9
crates/conjure_macros/src + + 94.96% + + + 94.96% + + 113 / 119 + 55.88%19 / 34
crates/enum_compatability_macro/src + + 100% + + + 100% + + 115 / 115 + 60%12 / 20
crates/uniplate/src + + 61% + + + 61% + + 158 / 259 + 48.53%33 / 68
crates/uniplate/src/test_common + + 0% + + + 0% + + 0 / 35 + 0%0 / 12
crates/uniplate/tests + + 43.48% + + + 43.48% + + 160 / 368 + 17.65%6 / 34
crates/uniplate_derive/src + + 96.9% + + + 96.9% + + 125 / 129 + 51.61%16 / 31
crates/uniplate_derive/src/utils + + 88.02% + + + 88.02% + + 191 / 217 + 50%28 / 56
crates/uniplate_derive/tests + + 100% + + + 100% + + 188 / 188 + 100%36 / 36
solvers/chuffed/src + + 0% + + + 0% + + 0 / 46 + 0%0 / 14
solvers/chuffed/tests + + 32.26% + + + 32.26% + + 20 / 62 + 60%3 / 5
solvers/kissat/src + + 96% + + + 96% + + 24 / 25 + 100%1 / 1
solvers/minion/src + + 69.14% + + + 69.14% + + 531 / 768 + 28.57%40 / 140
solvers/minion/tests + + 100% + + + 100% + + 31 / 31 + 100%2 / 2
+ + + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/lcov.info b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/lcov.info new file mode 100644 index 0000000000..ade44eaa28 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/lcov.info @@ -0,0 +1,10929 @@ +TN: +SF:conjure_oxide/tests/model_tests.rs +FN:11,model_tests::modify_domain +FNDA:1,model_tests::modify_domain +FNF:1 +FNH:1 +BRF:0 +BRH:0 +DA:11,1 +DA:12,1 +DA:13,1 +DA:14,1 +DA:15,1 +DA:16,1 +DA:17,1 +DA:18,1 +DA:19,1 +DA:20,1 +DA:21,1 +DA:22,1 +DA:23,1 +DA:24,1 +DA:25,1 +DA:26,1 +DA:28,1 +DA:29,1 +DA:30,1 +DA:31,1 +LF:20 +LH:20 +end_of_record +SF:crates/uniplate_derive/src/utils/parse.rs +FN:117,uniplate_derive::utils::parse::check_field_type +FN:74,uniplate_derive::utils::parse::parse_field_type +FN:76,uniplate_derive::utils::parse::parse_field_type::parse_type +FN:47,uniplate_derive::utils::parse::parse_type_argument +FN:117,uniplate_derive::utils::parse::check_field_type +FN:47,uniplate_derive::utils::parse::parse_type_argument +FN:117,uniplate_derive::utils::parse::check_field_type +FN:117,uniplate_derive::utils::parse::check_field_type +FN:76,uniplate_derive::utils::parse::parse_field_type::parse_type +FN:47,uniplate_derive::utils::parse::parse_type_argument +FN:47,uniplate_derive::utils::parse::parse_type_argument +FN:74,uniplate_derive::utils::parse::parse_field_type +FN:34,::span +FN:34,::span +FN:74,uniplate_derive::utils::parse::parse_field_type +FN:76,uniplate_derive::utils::parse::parse_field_type::parse_type +FN:34,::span +FN:34,::span +FN:76,uniplate_derive::utils::parse::parse_field_type::parse_type +FN:74,uniplate_derive::utils::parse::parse_field_type +FNDA:0,uniplate_derive::utils::parse::check_field_type +FNDA:0,uniplate_derive::utils::parse::parse_field_type +FNDA:0,uniplate_derive::utils::parse::parse_field_type::parse_type +FNDA:1,uniplate_derive::utils::parse::parse_type_argument +FNDA:1,uniplate_derive::utils::parse::check_field_type +FNDA:0,uniplate_derive::utils::parse::parse_type_argument +FNDA:0,uniplate_derive::utils::parse::check_field_type +FNDA:1,uniplate_derive::utils::parse::check_field_type +FNDA:1,uniplate_derive::utils::parse::parse_field_type::parse_type +FNDA:1,uniplate_derive::utils::parse::parse_type_argument +FNDA:0,uniplate_derive::utils::parse::parse_type_argument +FNDA:0,uniplate_derive::utils::parse::parse_field_type +FNDA:1,::span +FNDA:1,::span +FNDA:1,uniplate_derive::utils::parse::parse_field_type +FNDA:0,uniplate_derive::utils::parse::parse_field_type::parse_type +FNDA:0,::span +FNDA:0,::span +FNDA:1,uniplate_derive::utils::parse::parse_field_type::parse_type +FNDA:1,uniplate_derive::utils::parse::parse_field_type +FNF:20 +FNH:10 +BRF:0 +BRH:0 +DA:34,54 +DA:35,54 +DA:36,53 +DA:37,0 +DA:38,1 +DA:39,0 +DA:40,0 +DA:41,0 +DA:43,54 +DA:47,354 +DA:48,354 +DA:49,354 +DA:50,354 +DA:52,0 +DA:53,354 +DA:54,354 +DA:55,354 +DA:56,0 +DA:57,354 +DA:58,354 +DA:59,354 +DA:60,354 +DA:61,0 +DA:63,0 +DA:65,0 +DA:69,0 +DA:71,354 +DA:74,608 +DA:75,608 +DA:76,956 +DA:77,956 +DA:78,956 +DA:79,956 +DA:80,956 +DA:81,956 +DA:82,956 +DA:83,956 +DA:84,956 +DA:85,608 +DA:86,608 +DA:87,608 +DA:88,608 +DA:89,710 +DA:90,608 +DA:91,608 +DA:92,608 +DA:93,608 +DA:94,608 +DA:95,608 +DA:96,608 +DA:97,956 +DA:98,608 +DA:99,608 +DA:100,602 +DA:101,0 +DA:102,602 +DA:104,6 +DA:105,6 +DA:107,0 +DA:108,0 +DA:109,0 +DA:110,0 +DA:111,0 +DA:112,0 +DA:114,608 +DA:117,1330 +DA:118,1330 +DA:119,962 +DA:120,252 +DA:121,110 +DA:122,6 +DA:123,6 +DA:124,6 +DA:125,6 +DA:126,0 +DA:128,0 +DA:130,0 +DA:131,0 +DA:133,1330 +LF:79 +LH:58 +end_of_record +SF:crates/conjure_core/src/parse/example_models.rs +FN:31,conjure_core::parse::example_models::get_example_model::{closure#1} +FN:22,conjure_core::parse::example_models::get_example_model +FN:78,conjure_core::parse::example_models::get_example_model_by_path +FN:22,conjure_core::parse::example_models::get_example_model +FN:78,conjure_core::parse::example_models::get_example_model_by_path +FN:28,conjure_core::parse::example_models::get_example_model::{closure#0} +FN:31,conjure_core::parse::example_models::get_example_model::{closure#1} +FN:31,conjure_core::parse::example_models::get_example_model::{closure#1} +FN:78,conjure_core::parse::example_models::get_example_model_by_path +FN:28,conjure_core::parse::example_models::get_example_model::{closure#0} +FN:28,conjure_core::parse::example_models::get_example_model::{closure#0} +FN:22,conjure_core::parse::example_models::get_example_model +FNDA:0,conjure_core::parse::example_models::get_example_model::{closure#1} +FNDA:0,conjure_core::parse::example_models::get_example_model +FNDA:0,conjure_core::parse::example_models::get_example_model_by_path +FNDA:0,conjure_core::parse::example_models::get_example_model +FNDA:0,conjure_core::parse::example_models::get_example_model_by_path +FNDA:0,conjure_core::parse::example_models::get_example_model::{closure#0} +FNDA:0,conjure_core::parse::example_models::get_example_model::{closure#1} +FNDA:1,conjure_core::parse::example_models::get_example_model::{closure#1} +FNDA:1,conjure_core::parse::example_models::get_example_model_by_path +FNDA:1,conjure_core::parse::example_models::get_example_model::{closure#0} +FNDA:0,conjure_core::parse::example_models::get_example_model::{closure#0} +FNDA:1,conjure_core::parse::example_models::get_example_model +FNF:12 +FNH:4 +BRF:0 +BRH:0 +DA:22,45 +DA:24,45 +DA:25,45 +DA:28,249720 +DA:29,249720 +DA:30,249720 +DA:31,211410 +DA:32,225 +DA:34,30 +DA:35,30 +DA:36,249690 +DA:42,45 +DA:43,15 +DA:44,15 +DA:45,15 +DA:46,15 +DA:47,30 +DA:48,30 +DA:49,30 +DA:50,30 +DA:51,30 +DA:52,30 +DA:53,30 +DA:54,30 +DA:55,30 +DA:58,30 +DA:63,30 +DA:65,30 +DA:66,45 +DA:78,30 +DA:79,30 +DA:80,30 +DA:81,30 +DA:82,30 +DA:83,15 +DA:84,15 +DA:85,15 +DA:86,15 +DA:87,15 +DA:88,15 +DA:89,15 +DA:90,15 +DA:91,15 +DA:92,15 +DA:93,15 +DA:94,15 +DA:95,15 +DA:96,15 +DA:97,15 +DA:100,15 +DA:105,15 +DA:107,15 +DA:108,30 +LF:53 +LH:53 +end_of_record +SF:conjure_oxide/tests/generated_tests.rs +FN:19,generated_tests::main::{closure#0} +FN:91,generated_tests::assert_conjure_present +FN:17,generated_tests::main +FN:28,generated_tests::integration_test +FNDA:0,generated_tests::main::{closure#0} +FNDA:1,generated_tests::assert_conjure_present +FNDA:0,generated_tests::main +FNDA:1,generated_tests::integration_test +FNF:4 +FNH:2 +BRF:0 +BRH:0 +DA:17,0 +DA:18,0 +DA:19,0 +DA:20,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:25,0 +DA:28,9 +DA:29,9 +DA:30,9 +DA:31,9 +DA:32,9 +DA:33,9 +DA:34,0 +DA:35,0 +DA:36,0 +DA:37,0 +DA:38,9 +DA:41,9 +DA:42,9 +DA:43,0 +DA:44,9 +DA:46,9 +DA:47,9 +DA:48,9 +DA:49,9 +DA:50,9 +DA:51,0 +DA:52,9 +DA:54,9 +DA:57,9 +DA:58,9 +DA:59,9 +DA:60,0 +DA:61,9 +DA:63,9 +DA:64,9 +DA:65,9 +DA:66,0 +DA:67,9 +DA:69,9 +DA:72,9 +DA:73,9 +DA:74,9 +DA:75,0 +DA:76,9 +DA:78,9 +DA:79,9 +DA:80,0 +DA:81,9 +DA:83,9 +DA:85,9 +DA:87,9 +DA:88,9 +DA:91,1 +DA:92,1 +DA:93,1 +LF:58 +LH:40 +end_of_record +SF:conjure_oxide/src/utils/conjure.rs +FN:66,conjure_oxide::utils::conjure::get_minion_solutions +FN:16,::fmt +FN:25,>::from +FN:78,conjure_oxide::utils::conjure::get_minion_solutions::{closure#0} +FN:25,>::from +FN:30,conjure_oxide::utils::conjure::parse_essence_file +FN:93,conjure_oxide::utils::conjure::minion_solutions_to_json +FN:16,::fmt +FN:30,conjure_oxide::utils::conjure::parse_essence_file +FN:25,>::from +FN:78,conjure_oxide::utils::conjure::get_minion_solutions::{closure#0} +FN:16,::fmt +FN:30,conjure_oxide::utils::conjure::parse_essence_file +FN:93,conjure_oxide::utils::conjure::minion_solutions_to_json +FN:66,conjure_oxide::utils::conjure::get_minion_solutions +FN:78,conjure_oxide::utils::conjure::get_minion_solutions::{closure#0} +FN:66,conjure_oxide::utils::conjure::get_minion_solutions +FN:93,conjure_oxide::utils::conjure::minion_solutions_to_json +FNDA:1,conjure_oxide::utils::conjure::get_minion_solutions +FNDA:0,::fmt +FNDA:0,>::from +FNDA:0,conjure_oxide::utils::conjure::get_minion_solutions::{closure#0} +FNDA:0,>::from +FNDA:0,conjure_oxide::utils::conjure::parse_essence_file +FNDA:0,conjure_oxide::utils::conjure::minion_solutions_to_json +FNDA:0,::fmt +FNDA:1,conjure_oxide::utils::conjure::parse_essence_file +FNDA:0,>::from +FNDA:0,conjure_oxide::utils::conjure::get_minion_solutions::{closure#0} +FNDA:0,::fmt +FNDA:0,conjure_oxide::utils::conjure::parse_essence_file +FNDA:0,conjure_oxide::utils::conjure::minion_solutions_to_json +FNDA:0,conjure_oxide::utils::conjure::get_minion_solutions +FNDA:1,conjure_oxide::utils::conjure::get_minion_solutions::{closure#0} +FNDA:0,conjure_oxide::utils::conjure::get_minion_solutions +FNDA:1,conjure_oxide::utils::conjure::minion_solutions_to_json +FNF:18 +FNH:4 +BRF:0 +BRH:0 +DA:16,0 +DA:25,0 +DA:26,0 +DA:27,0 +DA:30,45 +DA:31,45 +DA:32,45 +DA:33,45 +DA:34,45 +DA:35,45 +DA:36,45 +DA:37,45 +DA:38,45 +DA:39,45 +DA:40,45 +DA:42,45 +DA:43,0 +DA:46,45 +DA:47,0 +DA:48,0 +DA:49,0 +DA:50,45 +DA:52,45 +DA:53,45 +DA:54,0 +DA:55,0 +DA:56,0 +DA:57,0 +DA:58,0 +DA:62,45 +DA:63,45 +DA:64,45 +DA:66,45 +DA:67,45 +DA:68,45 +DA:69,45 +DA:70,45 +DA:72,45 +DA:73,45 +DA:74,45 +DA:75,45 +DA:76,45 +DA:77,45 +DA:78,175 +DA:79,175 +DA:80,175 +DA:81,175 +DA:82,175 +DA:83,45 +DA:84,45 +DA:85,45 +DA:86,45 +DA:87,45 +DA:88,45 +DA:89,45 +DA:90,45 +DA:91,45 +DA:93,45 +DA:94,45 +DA:95,220 +DA:96,175 +DA:97,650 +DA:98,475 +DA:99,475 +DA:100,0 +DA:102,475 +DA:104,175 +DA:106,45 +DA:107,45 +DA:108,45 +LF:70 +LH:56 +end_of_record +SF:solvers/chuffed/tests/dummy_test.rs +FN:2,dummy_test::dummy +FNDA:1,dummy_test::dummy +FNF:1 +FNH:1 +BRF:0 +BRH:0 +DA:2,1 +DA:3,1 +DA:4,1 +LF:3 +LH:3 +end_of_record +SF:solvers/minion/tests/test_watchedor_reifyimply_1.rs +FN:29,test_watchedor_reifyimply_1::test_watchedor_reifyimply_1 +FN:57,test_watchedor_reifyimply_1::callback +FNDA:1,test_watchedor_reifyimply_1::test_watchedor_reifyimply_1 +FNDA:1,test_watchedor_reifyimply_1::callback +FNF:2 +FNH:2 +BRF:0 +BRH:0 +DA:29,1 +DA:30,1 +DA:31,1 +DA:32,1 +DA:33,1 +DA:34,1 +DA:35,1 +DA:36,1 +DA:37,1 +DA:38,1 +DA:39,1 +DA:40,1 +DA:41,1 +DA:42,1 +DA:43,1 +DA:44,1 +DA:45,1 +DA:46,1 +DA:47,1 +DA:48,1 +DA:49,1 +DA:51,1 +DA:52,1 +DA:53,1 +DA:54,1 +DA:57,7 +DA:58,7 +DA:59,7 +DA:60,7 +DA:61,7 +DA:62,7 +LF:31 +LH:31 +end_of_record +SF:crates/conjure_core/src/rule_engine/resolve_rules.rs +FN:45,conjure_core::rule_engine::resolve_rules::rule_sets_by_names +FN:152,conjure_core::rule_engine::resolve_rules::get_rules_vec::{closure#0} +FN:45,conjure_core::rule_engine::resolve_rules::rule_sets_by_names +FN:128,conjure_core::rule_engine::resolve_rules::rule_cmp +FN:15,::fmt +FN:152,conjure_core::rule_engine::resolve_rules::get_rules_vec::{closure#0} +FN:128,conjure_core::rule_engine::resolve_rules::rule_cmp +FN:150,conjure_core::rule_engine::resolve_rules::get_rules_vec +FN:15,::fmt +FN:70,conjure_core::rule_engine::resolve_rules::resolve_rule_sets +FN:29,conjure_core::rule_engine::resolve_rules::get_rule_set +FN:70,conjure_core::rule_engine::resolve_rules::resolve_rule_sets +FN:45,conjure_core::rule_engine::resolve_rules::rule_sets_by_names +FN:150,conjure_core::rule_engine::resolve_rules::get_rules_vec +FN:70,conjure_core::rule_engine::resolve_rules::resolve_rule_sets +FN:90,conjure_core::rule_engine::resolve_rules::get_rule_priorities +FN:128,conjure_core::rule_engine::resolve_rules::rule_cmp +FN:150,conjure_core::rule_engine::resolve_rules::get_rules_vec +FN:90,conjure_core::rule_engine::resolve_rules::get_rule_priorities +FN:90,conjure_core::rule_engine::resolve_rules::get_rule_priorities +FN:29,conjure_core::rule_engine::resolve_rules::get_rule_set +FN:29,conjure_core::rule_engine::resolve_rules::get_rule_set +FN:15,::fmt +FN:152,conjure_core::rule_engine::resolve_rules::get_rules_vec::{closure#0} +FNDA:0,conjure_core::rule_engine::resolve_rules::rule_sets_by_names +FNDA:1,conjure_core::rule_engine::resolve_rules::get_rules_vec::{closure#0} +FNDA:1,conjure_core::rule_engine::resolve_rules::rule_sets_by_names +FNDA:0,conjure_core::rule_engine::resolve_rules::rule_cmp +FNDA:0,::fmt +FNDA:0,conjure_core::rule_engine::resolve_rules::get_rules_vec::{closure#0} +FNDA:1,conjure_core::rule_engine::resolve_rules::rule_cmp +FNDA:0,conjure_core::rule_engine::resolve_rules::get_rules_vec +FNDA:0,::fmt +FNDA:0,conjure_core::rule_engine::resolve_rules::resolve_rule_sets +FNDA:0,conjure_core::rule_engine::resolve_rules::get_rule_set +FNDA:0,conjure_core::rule_engine::resolve_rules::resolve_rule_sets +FNDA:0,conjure_core::rule_engine::resolve_rules::rule_sets_by_names +FNDA:0,conjure_core::rule_engine::resolve_rules::get_rules_vec +FNDA:1,conjure_core::rule_engine::resolve_rules::resolve_rule_sets +FNDA:0,conjure_core::rule_engine::resolve_rules::get_rule_priorities +FNDA:0,conjure_core::rule_engine::resolve_rules::rule_cmp +FNDA:1,conjure_core::rule_engine::resolve_rules::get_rules_vec +FNDA:1,conjure_core::rule_engine::resolve_rules::get_rule_priorities +FNDA:0,conjure_core::rule_engine::resolve_rules::get_rule_priorities +FNDA:0,conjure_core::rule_engine::resolve_rules::get_rule_set +FNDA:1,conjure_core::rule_engine::resolve_rules::get_rule_set +FNDA:0,::fmt +FNDA:0,conjure_core::rule_engine::resolve_rules::get_rules_vec::{closure#0} +FNF:24 +FNH:7 +BRF:0 +BRH:0 +DA:15,0 +DA:16,0 +DA:17,0 +DA:18,0 +DA:19,0 +DA:29,180 +DA:30,180 +DA:31,180 +DA:32,0 +DA:34,180 +DA:45,180 +DA:46,180 +DA:47,180 +DA:48,180 +DA:50,360 +DA:51,180 +DA:52,180 +DA:53,180 +DA:54,180 +DA:57,180 +DA:58,180 +DA:70,180 +DA:71,180 +DA:72,180 +DA:73,180 +DA:74,180 +DA:76,180 +DA:77,180 +DA:78,180 +DA:80,180 +DA:81,180 +DA:82,180 +DA:90,165 +DA:91,165 +DA:92,165 +DA:93,165 +DA:95,660 +DA:96,4290 +DA:97,4290 +DA:98,0 +DA:99,0 +DA:100,0 +DA:101,4290 +DA:102,4290 +DA:103,4290 +DA:107,165 +DA:108,4455 +DA:109,4290 +DA:110,4290 +DA:112,165 +DA:113,165 +DA:128,19035 +DA:129,19035 +DA:130,19035 +DA:131,19035 +DA:132,19035 +DA:133,19035 +DA:134,19035 +DA:135,19035 +DA:136,19035 +DA:137,16755 +DA:138,2280 +DA:139,2280 +DA:140,2280 +DA:141,19035 +DA:150,165 +DA:151,165 +DA:152,19035 +DA:153,165 +DA:154,165 +LF:70 +LH:61 +end_of_record +SF:conjure_oxide/src/utils/json.rs +FN:53,conjure_oxide::utils::json::sort_json_object::{closure#0} +FN:7,conjure_oxide::utils::json::json_value_cmp +FN:68,conjure_oxide::utils::json::sort_json_object::{closure#2} +FN:62,conjure_oxide::utils::json::sort_json_object::{closure#1} +FN:62,conjure_oxide::utils::json::sort_json_object::{closure#1} +FN:68,conjure_oxide::utils::json::sort_json_object::{closure#2} +FN:48,conjure_oxide::utils::json::sort_json_object +FN:32,conjure_oxide::utils::json::sort_json_variables +FN:7,conjure_oxide::utils::json::json_value_cmp +FN:32,conjure_oxide::utils::json::sort_json_variables +FN:53,conjure_oxide::utils::json::sort_json_object::{closure#0} +FN:7,conjure_oxide::utils::json::json_value_cmp +FN:48,conjure_oxide::utils::json::sort_json_object +FN:32,conjure_oxide::utils::json::sort_json_variables +FN:62,conjure_oxide::utils::json::sort_json_object::{closure#1} +FN:48,conjure_oxide::utils::json::sort_json_object +FN:68,conjure_oxide::utils::json::sort_json_object::{closure#2} +FN:53,conjure_oxide::utils::json::sort_json_object::{closure#0} +FNDA:0,conjure_oxide::utils::json::sort_json_object::{closure#0} +FNDA:0,conjure_oxide::utils::json::json_value_cmp +FNDA:1,conjure_oxide::utils::json::sort_json_object::{closure#2} +FNDA:0,conjure_oxide::utils::json::sort_json_object::{closure#1} +FNDA:0,conjure_oxide::utils::json::sort_json_object::{closure#1} +FNDA:0,conjure_oxide::utils::json::sort_json_object::{closure#2} +FNDA:0,conjure_oxide::utils::json::sort_json_object +FNDA:1,conjure_oxide::utils::json::sort_json_variables +FNDA:1,conjure_oxide::utils::json::json_value_cmp +FNDA:0,conjure_oxide::utils::json::sort_json_variables +FNDA:1,conjure_oxide::utils::json::sort_json_object::{closure#0} +FNDA:0,conjure_oxide::utils::json::json_value_cmp +FNDA:0,conjure_oxide::utils::json::sort_json_object +FNDA:0,conjure_oxide::utils::json::sort_json_variables +FNDA:1,conjure_oxide::utils::json::sort_json_object::{closure#1} +FNDA:1,conjure_oxide::utils::json::sort_json_object +FNDA:0,conjure_oxide::utils::json::sort_json_object::{closure#2} +FNDA:0,conjure_oxide::utils::json::sort_json_object::{closure#0} +FNF:18 +FNH:6 +BRF:0 +BRH:0 +DA:7,590 +DA:8,590 +DA:9,0 +DA:10,0 +DA:11,0 +DA:12,0 +DA:13,0 +DA:14,0 +DA:15,0 +DA:17,135 +DA:18,135 +DA:19,135 +DA:20,135 +DA:21,135 +DA:22,0 +DA:24,0 +DA:26,455 +DA:28,590 +DA:32,90 +DA:33,90 +DA:34,90 +DA:35,90 +DA:36,90 +DA:37,90 +DA:39,0 +DA:41,90 +DA:48,10230 +DA:49,10230 +DA:50,4600 +DA:51,4600 +DA:52,4600 +DA:53,5560 +DA:54,5560 +DA:55,90 +DA:57,5470 +DA:59,5560 +DA:60,4600 +DA:61,4600 +DA:62,4600 +DA:63,4600 +DA:65,1875 +DA:66,1875 +DA:67,1875 +DA:68,4535 +DA:69,1875 +DA:70,1875 +DA:71,1875 +DA:72,90 +DA:73,1785 +DA:75,1875 +DA:77,3755 +DA:79,10230 +LF:52 +LH:42 +end_of_record +SF:crates/conjure_core/src/metadata.rs +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:5,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:11,::default +FN:11,::default +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:17,::new +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:5,<::deserialize::__Field as serde::de::Deserialize>::deserialize::> +FN:5,<::deserialize::__Field as serde::de::Deserialize>::deserialize::> +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::<_> +FN:23,::fmt +FN:5,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:11,::default +FN:5,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:23,::fmt +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::> +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::> +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::<_> +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::> +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FN:17,::new +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::<_> +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:23,::fmt +FN:17,::new +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,::default +FNDA:0,::default +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:1,::new +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:1,<::deserialize::__Field as serde::de::Deserialize>::deserialize::> +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::<_> +FNDA:0,::fmt +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::default +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,::fmt +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:1,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FNDA:0,::new +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,::fmt +FNDA:0,::new +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:1,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::> +FNF:41 +FNH:4 +BRF:0 +BRH:0 +DA:5,3020 +DA:11,0 +DA:12,0 +DA:13,0 +DA:17,6150 +DA:18,6150 +DA:19,6150 +DA:23,0 +DA:24,0 +DA:25,0 +LF:10 +LH:4 +end_of_record +SF:solvers/chuffed/tests/chuffed_basic_run.rs +FN:11,chuffed_basic_run::post_constraints +FN:42,chuffed_basic_run::run_basic_problem +FN:35,callback +FNDA:0,chuffed_basic_run::post_constraints +FNDA:1,chuffed_basic_run::run_basic_problem +FNDA:0,callback +FNF:3 +FNH:1 +BRF:0 +BRH:0 +DA:11,0 +DA:12,0 +DA:13,0 +DA:14,0 +DA:15,0 +DA:16,0 +DA:17,0 +DA:18,0 +DA:19,0 +DA:20,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:24,0 +DA:25,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:35,0 +DA:36,0 +DA:37,0 +DA:42,1 +DA:43,1 +DA:44,1 +DA:45,1 +DA:46,1 +DA:47,1 +DA:48,0 +DA:49,0 +DA:50,0 +DA:51,0 +DA:52,0 +DA:53,0 +DA:54,0 +DA:55,0 +DA:56,0 +DA:57,0 +DA:58,0 +DA:59,0 +DA:60,0 +DA:61,0 +DA:62,0 +DA:63,0 +DA:64,0 +DA:65,0 +DA:67,1 +LF:49 +LH:7 +end_of_record +SF:crates/conjure_core/src/ast/expressions.rs +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,::uniplate::{closure#17} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::uniplate::{closure#19} +FN:15,::uniplate::{closure#15} +FN:15,::is_nothing +FN:15,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::uniplate::{closure#2} +FN:15,::uniplate::{closure#2} +FN:15,::is_or +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:138,conjure_core::ast::expressions::display_expressions::{closure#0} +FN:15,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:15,::is_and +FN:15,::is_sum_eq +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::is_all_diff +FN:15,::is_constant +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::uniplate::{closure#21} +FN:15,::uniplate::{closure#3} +FN:15,::uniplate::{closure#5} +FN:15,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:152,::fmt +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,::uniplate::{closure#21} +FN:15,::uniplate::{closure#9} +FN:15,::uniplate::{closure#23} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::uniplate::{closure#1} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,::is_nothing +FN:15,::is_and +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::is_ineq +FN:15,::is_not +FN:120,::bounds::{closure#1} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:97,::bounds::{closure#0} +FN:15,::uniplate::{closure#5} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:120,::bounds::{closure#1} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,::uniplate::{closure#21} +FN:15,::is_eq +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:123,::bounds::{closure#2} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::uniplate::{closure#0} +FN:15,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:15,::is_leq +FN:138,conjure_core::ast::expressions::display_expressions::{closure#0} +FN:15,::is_sum_leq +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,::uniplate::{closure#11} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::is_leq +FN:15,::is_lt +FN:15,::is_nothing +FN:138,conjure_core::ast::expressions::display_expressions::{closure#0} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,::uniplate::{closure#3} +FN:15,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FN:15,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:132,conjure_core::ast::expressions::display_expressions +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,::is_gt +FN:15,::is_neq +FN:15,::uniplate::{closure#9} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,::is_min +FN:15,::uniplate::{closure#11} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,::uniplate::{closure#8} +FN:15,::uniplate::{closure#6} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,::is_reference +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:15,::is_sum_eq +FN:15,::uniplate::{closure#4} +FN:97,::bounds::{closure#0} +FN:15,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:15,::is_sum_geq +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,::is_min +FN:15,::uniplate::{closure#10} +FN:15,::is_sum_geq +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::uniplate::{closure#1} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::uniplate +FN:15,::uniplate::{closure#13} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:124,::bounds::{closure#3} +FN:15,::uniplate::{closure#15} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:132,conjure_core::ast::expressions::display_expressions +FN:15,::uniplate::{closure#7} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,::uniplate::{closure#9} +FN:152,::fmt +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,::is_geq +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,::uniplate::{closure#25} +FN:15,::uniplate::{closure#7} +FN:15,::uniplate::{closure#5} +FN:15,::uniplate +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::is_neq +FN:15,::uniplate::{closure#14} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::uniplate::{closure#10} +FN:15,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,::is_ineq +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:124,::bounds::{closure#3} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,::uniplate::{closure#10} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::uniplate::{closure#23} +FN:15,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:15,::uniplate::{closure#25} +FN:15,::is_reference +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::uniplate::{closure#11} +FN:15,::uniplate::{closure#18} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,::uniplate::{closure#17} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:15,::is_constant +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::uniplate::{closure#16} +FN:15,::uniplate::{closure#18} +FN:15,::uniplate::{closure#20} +FN:15,::is_or +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::is_neq +FN:15,::uniplate::{closure#4} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,::is_eq +FN:15,::uniplate::{closure#6} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::uniplate::{closure#8} +FN:15,::is_lt +FN:15,::is_all_diff +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,::is_sum_leq +FN:15,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:132,conjure_core::ast::expressions::display_expressions +FN:15,::is_ineq +FN:15,::uniplate::{closure#13} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,::is_gt +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::uniplate::{closure#17} +FN:15,::uniplate::{closure#19} +FN:15,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::uniplate::{closure#14} +FN:15,::uniplate::{closure#16} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,::is_min +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:15,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FN:15,::uniplate::{closure#12} +FN:15,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FN:15,::uniplate::{closure#19} +FN:15,::is_not +FN:15,::uniplate::{closure#18} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,::is_eq +FN:15,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:15,::is_reference +FN:15,::is_geq +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:15,::uniplate::{closure#12} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::is_gt +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,::uniplate::{closure#20} +FN:15,::uniplate::{closure#22} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::is_constant +FN:15,::uniplate::{closure#12} +FN:15,::uniplate::{closure#26} +FN:15,::is_and +FN:15,::is_or +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,::is_sum +FN:15,::is_sum +FN:15,::uniplate::{closure#0} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:95,::bounds +FN:15,::uniplate::{closure#22} +FN:15,::uniplate::{closure#24} +FN:15,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:124,::bounds::{closure#3} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:15,::is_sum_leq +FN:15,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::uniplate::{closure#13} +FN:15,::uniplate::{closure#15} +FN:15,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,::is_geq +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:95,::bounds +FN:15,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FN:15,::uniplate::{closure#0} +FN:15,::is_sum_eq +FN:15,::uniplate::{closure#6} +FN:15,::uniplate::{closure#25} +FN:15,::uniplate::{closure#8} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::uniplate::{closure#26} +FN:15,::is_sum +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:120,::bounds::{closure#1} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,::is_all_diff +FN:15,::uniplate::{closure#23} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:97,::bounds::{closure#0} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,::uniplate::{closure#14} +FN:15,::uniplate::{closure#16} +FN:95,::bounds +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::is_not +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::is_lt +FN:15,::uniplate::{closure#3} +FN:15,::uniplate +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:15,::uniplate::{closure#1} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:152,::fmt +FN:15,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FN:15,::uniplate::{closure#24} +FN:15,::uniplate::{closure#26} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:15,::uniplate::{closure#24} +FN:15,::uniplate::{closure#22} +FN:15,::uniplate::{closure#20} +FN:15,::is_sum_geq +FN:15,::uniplate::{closure#2} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:15,::uniplate::{closure#4} +FN:15,::is_leq +FN:123,::bounds::{closure#2} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,::uniplate::{closure#7} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:123,::bounds::{closure#2} +FN:15,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:1,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:1,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:1,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,::uniplate::{closure#17} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::uniplate::{closure#19} +FNDA:0,::uniplate::{closure#15} +FNDA:0,::is_nothing +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::uniplate::{closure#2} +FNDA:0,::uniplate::{closure#2} +FNDA:0,::is_or +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,conjure_core::ast::expressions::display_expressions::{closure#0} +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,::is_and +FNDA:0,::is_sum_eq +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::is_all_diff +FNDA:0,::is_constant +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:1,::uniplate::{closure#21} +FNDA:0,::uniplate::{closure#3} +FNDA:0,::uniplate::{closure#5} +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::fmt +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,::uniplate::{closure#21} +FNDA:0,::uniplate::{closure#9} +FNDA:0,::uniplate::{closure#23} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::uniplate::{closure#1} +FNDA:1,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:1,::is_nothing +FNDA:0,::is_and +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::is_ineq +FNDA:0,::is_not +FNDA:1,::bounds::{closure#1} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::bounds::{closure#0} +FNDA:0,::uniplate::{closure#5} +FNDA:1,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,::bounds::{closure#1} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::uniplate::{closure#21} +FNDA:0,::is_eq +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:1,::bounds::{closure#2} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::uniplate::{closure#0} +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,::is_leq +FNDA:0,conjure_core::ast::expressions::display_expressions::{closure#0} +FNDA:0,::is_sum_leq +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,::uniplate::{closure#11} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::is_leq +FNDA:0,::is_lt +FNDA:0,::is_nothing +FNDA:0,conjure_core::ast::expressions::display_expressions::{closure#0} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::uniplate::{closure#3} +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,conjure_core::ast::expressions::display_expressions +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::is_gt +FNDA:0,::is_neq +FNDA:0,::uniplate::{closure#9} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,::is_min +FNDA:0,::uniplate::{closure#11} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:1,::uniplate::{closure#8} +FNDA:1,::uniplate::{closure#6} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,::is_reference +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,::is_sum_eq +FNDA:0,::uniplate::{closure#4} +FNDA:0,::bounds::{closure#0} +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::is_sum_geq +FNDA:1,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,::is_min +FNDA:0,::uniplate::{closure#10} +FNDA:0,::is_sum_geq +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::uniplate::{closure#1} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::uniplate +FNDA:0,::uniplate::{closure#13} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::bounds::{closure#3} +FNDA:0,::uniplate::{closure#15} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,conjure_core::ast::expressions::display_expressions +FNDA:0,::uniplate::{closure#7} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,::uniplate::{closure#9} +FNDA:0,::fmt +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::is_geq +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:1,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,::uniplate::{closure#25} +FNDA:1,::uniplate::{closure#7} +FNDA:0,::uniplate::{closure#5} +FNDA:1,::uniplate +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:1,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::is_neq +FNDA:0,::uniplate::{closure#14} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:1,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::uniplate::{closure#10} +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,::is_ineq +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::bounds::{closure#3} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,::uniplate::{closure#10} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::uniplate::{closure#23} +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,::uniplate::{closure#25} +FNDA:0,::is_reference +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::uniplate::{closure#11} +FNDA:0,::uniplate::{closure#18} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:1,::uniplate::{closure#17} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,::is_constant +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::uniplate::{closure#16} +FNDA:0,::uniplate::{closure#18} +FNDA:0,::uniplate::{closure#20} +FNDA:0,::is_or +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::is_neq +FNDA:0,::uniplate::{closure#4} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::is_eq +FNDA:0,::uniplate::{closure#6} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::uniplate::{closure#8} +FNDA:0,::is_lt +FNDA:0,::is_all_diff +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::is_sum_leq +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,conjure_core::ast::expressions::display_expressions +FNDA:0,::is_ineq +FNDA:0,::uniplate::{closure#13} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,::is_gt +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::uniplate::{closure#17} +FNDA:0,::uniplate::{closure#19} +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::uniplate::{closure#14} +FNDA:0,::uniplate::{closure#16} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:1,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,::is_min +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FNDA:0,::uniplate::{closure#12} +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FNDA:1,::uniplate::{closure#19} +FNDA:0,::is_not +FNDA:0,::uniplate::{closure#18} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::is_eq +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::is_reference +FNDA:0,::is_geq +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,::uniplate::{closure#12} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::is_gt +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::uniplate::{closure#20} +FNDA:0,::uniplate::{closure#22} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:1,::is_constant +FNDA:0,::uniplate::{closure#12} +FNDA:1,::uniplate::{closure#26} +FNDA:0,::is_and +FNDA:0,::is_or +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::is_sum +FNDA:0,::is_sum +FNDA:0,::uniplate::{closure#0} +FNDA:1,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,::bounds +FNDA:0,::uniplate::{closure#22} +FNDA:0,::uniplate::{closure#24} +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FNDA:1,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:1,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:1,::bounds::{closure#3} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,::is_sum_leq +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::uniplate::{closure#13} +FNDA:0,::uniplate::{closure#15} +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,::is_geq +FNDA:1,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::bounds +FNDA:1,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FNDA:0,::uniplate::{closure#0} +FNDA:0,::is_sum_eq +FNDA:0,::uniplate::{closure#6} +FNDA:1,::uniplate::{closure#25} +FNDA:0,::uniplate::{closure#8} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::uniplate::{closure#26} +FNDA:0,::is_sum +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::bounds::{closure#1} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::is_all_diff +FNDA:1,::uniplate::{closure#23} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:1,::bounds::{closure#0} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:1,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::uniplate::{closure#14} +FNDA:0,::uniplate::{closure#16} +FNDA:1,::bounds +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::is_not +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::is_lt +FNDA:0,::uniplate::{closure#3} +FNDA:0,::uniplate +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,::uniplate::{closure#1} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::fmt +FNDA:1,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FNDA:0,::uniplate::{closure#24} +FNDA:0,::uniplate::{closure#26} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:1,::uniplate::{closure#24} +FNDA:1,::uniplate::{closure#22} +FNDA:1,::uniplate::{closure#20} +FNDA:0,::is_sum_geq +FNDA:0,::uniplate::{closure#2} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::uniplate::{closure#4} +FNDA:0,::is_leq +FNDA:0,::bounds::{closure#2} +FNDA:1,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,::uniplate::{closure#7} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::bounds::{closure#2} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNF:338 +FNH:38 +BRF:0 +BRH:0 +DA:15,73920 +DA:95,225 +DA:96,0 +DA:97,150 +DA:98,0 +DA:99,0 +DA:100,0 +DA:101,0 +DA:102,0 +DA:103,0 +DA:104,0 +DA:105,0 +DA:106,0 +DA:107,0 +DA:108,0 +DA:109,0 +DA:112,0 +DA:114,75 +DA:115,75 +DA:116,0 +DA:117,75 +DA:118,75 +DA:119,75 +DA:120,150 +DA:121,75 +DA:123,150 +DA:124,150 +DA:127,0 +DA:129,225 +DA:132,0 +DA:133,0 +DA:134,0 +DA:135,0 +DA:136,0 +DA:137,0 +DA:138,0 +DA:139,0 +DA:140,0 +DA:141,0 +DA:143,0 +DA:144,0 +DA:145,0 +DA:146,0 +DA:147,0 +DA:149,0 +DA:152,0 +DA:153,0 +DA:154,0 +DA:155,0 +DA:156,0 +DA:157,0 +DA:158,0 +DA:160,0 +DA:161,0 +DA:163,0 +DA:164,0 +DA:166,0 +DA:167,0 +DA:169,0 +DA:170,0 +DA:172,0 +DA:173,0 +DA:175,0 +DA:176,0 +DA:178,0 +DA:179,0 +DA:181,0 +DA:182,0 +DA:184,0 +DA:185,0 +DA:187,0 +DA:188,0 +DA:189,0 +DA:190,0 +DA:191,0 +DA:192,0 +DA:193,0 +DA:194,0 +DA:196,0 +DA:197,0 +DA:198,0 +DA:199,0 +DA:200,0 +DA:201,0 +DA:202,0 +DA:203,0 +DA:205,0 +DA:206,0 +DA:207,0 +DA:208,0 +DA:209,0 +DA:210,0 +DA:211,0 +DA:212,0 +DA:214,0 +DA:216,0 +LF:96 +LH:13 +end_of_record +SF:crates/uniplate/tests/expr_stmt_manual.rs +FN:415,expr_stmt_manual::universe_bi_multitype +FN:80,::uniplate::{closure#2} +FN:166,>::biplate::{closure#0} +FN:256,>::biplate +FN:188,>::biplate::{closure#2} +FN:326,::uniplate::{closure#4} +FN:128,::uniplate::{closure#6} +FN:223,>::biplate::{closure#5} +FN:150,>::biplate::{closure#0} +FN:243,>::biplate::{closure#6} +FN:268,>::biplate +FN:201,>::biplate::{closure#4} +FN:138,>::biplate +FN:317,::uniplate::{closure#3} +FN:259,>::biplate::{closure#0} +FN:42,::uniplate::{closure#0} +FN:174,>::biplate::{closure#1} +FN:349,::uniplate::{closure#5} +FN:313,::uniplate::{closure#2} +FN:113,::uniplate::{closure#4} +FN:283,::uniplate +FN:298,::uniplate::{closure#1} +FN:61,::uniplate::{closure#1} +FN:197,>::biplate::{closure#3}::{closure#0} +FN:32,::uniplate +FN:271,>::biplate::{closure#0} +FN:322,::uniplate::{closure#3}::{closure#0} +FN:120,::uniplate::{closure#5} +FN:382,expr_stmt_manual::children_bi_multitype +FN:369,::uniplate::{closure#6} +FN:99,::uniplate::{closure#3} +FN:288,::uniplate::{closure#0} +FN:160,>::biplate +FN:192,>::biplate::{closure#3} +FNDA:1,expr_stmt_manual::universe_bi_multitype +FNDA:0,::uniplate::{closure#2} +FNDA:0,>::biplate::{closure#0} +FNDA:1,>::biplate +FNDA:1,>::biplate::{closure#2} +FNDA:0,::uniplate::{closure#4} +FNDA:0,::uniplate::{closure#6} +FNDA:0,>::biplate::{closure#5} +FNDA:0,>::biplate::{closure#0} +FNDA:0,>::biplate::{closure#6} +FNDA:0,>::biplate +FNDA:0,>::biplate::{closure#4} +FNDA:0,>::biplate +FNDA:0,::uniplate::{closure#3} +FNDA:0,>::biplate::{closure#0} +FNDA:0,::uniplate::{closure#0} +FNDA:0,>::biplate::{closure#1} +FNDA:0,::uniplate::{closure#5} +FNDA:0,::uniplate::{closure#2} +FNDA:0,::uniplate::{closure#4} +FNDA:0,::uniplate +FNDA:0,::uniplate::{closure#1} +FNDA:0,::uniplate::{closure#1} +FNDA:0,>::biplate::{closure#3}::{closure#0} +FNDA:1,::uniplate +FNDA:0,>::biplate::{closure#0} +FNDA:0,::uniplate::{closure#3}::{closure#0} +FNDA:0,::uniplate::{closure#5} +FNDA:1,expr_stmt_manual::children_bi_multitype +FNDA:0,::uniplate::{closure#6} +FNDA:0,::uniplate::{closure#3} +FNDA:0,::uniplate::{closure#0} +FNDA:1,>::biplate +FNDA:0,>::biplate::{closure#3} +FNF:34 +FNH:6 +BRF:0 +BRH:0 +DA:32,8 +DA:33,8 +DA:34,2 +DA:35,2 +DA:36,2 +DA:37,2 +DA:38,2 +DA:39,2 +DA:40,2 +DA:41,2 +DA:42,2 +DA:43,0 +DA:44,0 +DA:45,0 +DA:46,0 +DA:47,0 +DA:48,0 +DA:49,2 +DA:50,2 +DA:51,2 +DA:53,0 +DA:54,0 +DA:55,0 +DA:56,0 +DA:57,0 +DA:58,0 +DA:59,0 +DA:60,0 +DA:61,0 +DA:62,0 +DA:63,0 +DA:64,0 +DA:65,0 +DA:66,0 +DA:67,0 +DA:68,0 +DA:69,0 +DA:70,0 +DA:72,0 +DA:73,0 +DA:74,0 +DA:75,0 +DA:76,0 +DA:77,0 +DA:78,0 +DA:79,0 +DA:80,0 +DA:81,0 +DA:82,0 +DA:83,0 +DA:84,0 +DA:85,0 +DA:86,0 +DA:87,0 +DA:88,0 +DA:89,0 +DA:91,0 +DA:92,0 +DA:93,0 +DA:94,0 +DA:95,0 +DA:96,0 +DA:97,0 +DA:98,0 +DA:99,0 +DA:100,0 +DA:101,0 +DA:102,0 +DA:103,0 +DA:104,0 +DA:105,0 +DA:106,0 +DA:107,0 +DA:108,0 +DA:111,3 +DA:112,3 +DA:113,3 +DA:114,0 +DA:115,0 +DA:116,3 +DA:117,3 +DA:118,3 +DA:119,3 +DA:120,3 +DA:121,0 +DA:122,0 +DA:123,3 +DA:124,3 +DA:126,0 +DA:127,0 +DA:128,0 +DA:129,0 +DA:130,0 +DA:131,0 +DA:132,0 +DA:134,8 +DA:138,0 +DA:139,0 +DA:140,0 +DA:141,0 +DA:142,0 +DA:143,0 +DA:144,0 +DA:145,0 +DA:146,0 +DA:147,0 +DA:148,0 +DA:149,0 +DA:150,0 +DA:151,0 +DA:152,0 +DA:153,0 +DA:154,0 +DA:155,0 +DA:160,12 +DA:161,12 +DA:162,4 +DA:163,4 +DA:164,4 +DA:165,4 +DA:166,4 +DA:167,4 +DA:168,4 +DA:169,4 +DA:170,4 +DA:171,4 +DA:172,4 +DA:173,4 +DA:174,4 +DA:175,0 +DA:176,0 +DA:177,0 +DA:178,4 +DA:179,4 +DA:180,4 +DA:182,4 +DA:183,4 +DA:184,4 +DA:185,4 +DA:186,4 +DA:187,4 +DA:188,4 +DA:189,4 +DA:190,4 +DA:191,4 +DA:192,4 +DA:193,0 +DA:194,0 +DA:197,0 +DA:198,4 +DA:199,4 +DA:200,4 +DA:201,4 +DA:202,0 +DA:203,0 +DA:205,0 +DA:206,0 +DA:207,4 +DA:208,4 +DA:209,4 +DA:212,2 +DA:213,2 +DA:214,2 +DA:215,2 +DA:216,2 +DA:217,2 +DA:218,2 +DA:219,2 +DA:220,2 +DA:221,2 +DA:222,2 +DA:223,2 +DA:224,0 +DA:225,0 +DA:226,0 +DA:227,0 +DA:228,0 +DA:229,0 +DA:230,0 +DA:231,2 +DA:232,2 +DA:233,2 +DA:235,2 +DA:236,2 +DA:237,2 +DA:238,2 +DA:239,2 +DA:240,2 +DA:241,2 +DA:242,2 +DA:243,2 +DA:244,0 +DA:245,0 +DA:246,0 +DA:247,2 +DA:248,2 +DA:249,2 +DA:252,12 +DA:256,12 +DA:257,12 +DA:258,12 +DA:259,12 +DA:260,0 +DA:261,0 +DA:262,12 +DA:263,12 +DA:264,12 +DA:268,0 +DA:269,0 +DA:270,0 +DA:271,0 +DA:272,0 +DA:273,0 +DA:274,0 +DA:275,0 +DA:276,0 +DA:283,0 +DA:284,0 +DA:285,0 +DA:286,0 +DA:287,0 +DA:288,0 +DA:289,0 +DA:290,0 +DA:291,0 +DA:292,0 +DA:293,0 +DA:294,0 +DA:295,0 +DA:296,0 +DA:297,0 +DA:298,0 +DA:299,0 +DA:300,0 +DA:301,0 +DA:302,0 +DA:303,0 +DA:304,0 +DA:306,0 +DA:307,0 +DA:308,0 +DA:309,0 +DA:310,0 +DA:311,0 +DA:312,0 +DA:313,0 +DA:314,0 +DA:315,0 +DA:316,0 +DA:317,0 +DA:318,0 +DA:319,0 +DA:322,0 +DA:323,0 +DA:324,0 +DA:325,0 +DA:326,0 +DA:327,0 +DA:328,0 +DA:330,0 +DA:331,0 +DA:332,0 +DA:333,0 +DA:334,0 +DA:336,0 +DA:337,0 +DA:338,0 +DA:339,0 +DA:340,0 +DA:341,0 +DA:342,0 +DA:343,0 +DA:344,0 +DA:345,0 +DA:346,0 +DA:347,0 +DA:348,0 +DA:349,0 +DA:350,0 +DA:351,0 +DA:352,0 +DA:353,0 +DA:354,0 +DA:355,0 +DA:356,0 +DA:357,0 +DA:358,0 +DA:359,0 +DA:361,0 +DA:362,0 +DA:363,0 +DA:364,0 +DA:365,0 +DA:366,0 +DA:367,0 +DA:368,0 +DA:369,0 +DA:370,0 +DA:371,0 +DA:372,0 +DA:373,0 +DA:374,0 +DA:375,0 +DA:378,0 +DA:382,1 +DA:383,1 +DA:384,1 +DA:385,1 +DA:386,1 +DA:387,1 +DA:388,1 +DA:389,1 +DA:390,1 +DA:391,1 +DA:392,1 +DA:393,1 +DA:394,1 +DA:395,1 +DA:396,1 +DA:397,1 +DA:398,1 +DA:399,1 +DA:400,1 +DA:401,1 +DA:402,1 +DA:403,1 +DA:404,1 +DA:405,1 +DA:407,1 +DA:408,1 +DA:409,1 +DA:410,1 +DA:411,1 +DA:412,1 +DA:415,1 +DA:416,1 +DA:417,1 +DA:418,1 +DA:419,1 +DA:420,1 +DA:421,1 +DA:422,1 +DA:423,1 +DA:424,1 +DA:425,1 +DA:426,1 +DA:427,1 +DA:428,1 +DA:429,1 +DA:430,1 +DA:431,1 +DA:432,1 +DA:433,1 +DA:434,1 +DA:435,1 +DA:436,1 +DA:437,1 +DA:438,1 +DA:440,1 +DA:441,1 +DA:442,1 +DA:443,1 +DA:444,1 +DA:445,1 +DA:446,1 +DA:447,1 +DA:448,1 +DA:449,1 +LF:368 +LH:160 +end_of_record +SF:crates/conjure_core/src/ast/variables.rs +FN:7,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::<_> +FN:7,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:7,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:13,::new +FN:13,::new +FN:7,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:7,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::> +FN:7,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:7,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:7,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:7,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:7,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:7,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:7,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:13,::new +FN:7,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:7,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:7,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FN:7,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FN:7,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:7,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::<_> +FN:7,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::> +FN:7,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:19,::fmt +FN:19,::fmt +FN:7,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:7,<::deserialize::__Field as serde::de::Deserialize>::deserialize::> +FN:19,::fmt +FN:7,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:7,<::deserialize::__Field as serde::de::Deserialize>::deserialize::> +FN:7,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:7,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::<_> +FN:7,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:7,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::> +FN:7,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:7,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::> +FN:7,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:7,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::new +FNDA:0,::new +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:1,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:1,::new +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:1,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,::fmt +FNDA:0,::fmt +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:1,<::deserialize::__Field as serde::de::Deserialize>::deserialize::> +FNDA:0,::fmt +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::<_> +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNF:38 +FNH:4 +BRF:0 +BRH:0 +DA:7,410 +DA:13,75 +DA:14,75 +DA:15,75 +DA:19,0 +DA:20,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:24,0 +DA:25,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:35,0 +DA:38,0 +LF:19 +LH:4 +end_of_record +SF:solvers/chuffed/tests/chuffed_cpp_run.rs +FN:4,chuffed_cpp_run::run_cpp_problem +FNDA:1,chuffed_cpp_run::run_cpp_problem +FNF:1 +FNH:1 +BRF:0 +BRH:0 +DA:4,1 +DA:5,1 +DA:6,1 +DA:7,1 +DA:8,1 +DA:9,1 +DA:10,1 +DA:11,1 +DA:12,1 +DA:14,1 +LF:10 +LH:10 +end_of_record +SF:solvers/minion/src/lib.rs +FN:29,rust_out::main +FN:40,rust_out::main::_doctest_main_solvers_minion_src_lib_rs_28_0::callback +FN:29,rust_out::main::_doctest_main_solvers_minion_src_lib_rs_28_0 +FNDA:1,rust_out::main +FNDA:1,rust_out::main::_doctest_main_solvers_minion_src_lib_rs_28_0::callback +FNDA:1,rust_out::main::_doctest_main_solvers_minion_src_lib_rs_28_0 +FNF:3 +FNH:3 +BRF:0 +BRH:0 +DA:29,1 +DA:30,1 +DA:31,1 +DA:32,1 +DA:33,1 +DA:34,1 +DA:35,1 +DA:36,1 +DA:37,1 +DA:38,1 +DA:39,1 +DA:40,1 +DA:41,1 +DA:42,1 +DA:43,1 +DA:44,1 +DA:45,1 +DA:46,1 +DA:47,1 +DA:48,1 +DA:49,1 +DA:50,1 +DA:51,1 +DA:52,1 +DA:53,1 +DA:54,1 +DA:55,1 +DA:56,1 +DA:57,1 +DA:58,1 +DA:59,1 +DA:60,1 +DA:61,1 +DA:62,1 +DA:63,1 +DA:64,1 +DA:65,1 +DA:66,1 +DA:67,1 +DA:68,1 +DA:69,1 +DA:70,1 +DA:71,1 +DA:72,1 +DA:73,1 +DA:74,1 +DA:75,1 +DA:76,1 +DA:77,1 +DA:78,1 +DA:79,1 +DA:80,1 +DA:81,1 +DA:82,1 +DA:83,1 +DA:84,1 +DA:85,1 +DA:86,1 +DA:87,1 +DA:88,1 +DA:89,1 +DA:90,1 +DA:91,1 +DA:92,1 +DA:93,1 +DA:94,1 +DA:95,1 +DA:96,1 +DA:97,1 +DA:98,1 +DA:99,1 +DA:100,1 +DA:101,1 +LF:73 +LH:73 +end_of_record +SF:conjure_oxide/src/find_conjure.rs +FN:25,conjure_oxide::find_conjure::conjure_executable::{closure#0} +FN:25,conjure_oxide::find_conjure::conjure_executable::{closure#0} +FN:25,conjure_oxide::find_conjure::conjure_executable::{closure#0} +FN:9,conjure_oxide::find_conjure::conjure_executable +FN:9,conjure_oxide::find_conjure::conjure_executable +FN:9,conjure_oxide::find_conjure::conjure_executable +FNDA:0,conjure_oxide::find_conjure::conjure_executable::{closure#0} +FNDA:0,conjure_oxide::find_conjure::conjure_executable::{closure#0} +FNDA:0,conjure_oxide::find_conjure::conjure_executable::{closure#0} +FNDA:0,conjure_oxide::find_conjure::conjure_executable +FNDA:0,conjure_oxide::find_conjure::conjure_executable +FNDA:1,conjure_oxide::find_conjure::conjure_executable +FNF:6 +FNH:1 +BRF:0 +BRH:0 +DA:9,5 +DA:10,5 +DA:11,5 +DA:12,5 +DA:13,5 +DA:15,5 +DA:16,0 +DA:17,5 +DA:18,5 +DA:19,5 +DA:20,5 +DA:21,5 +DA:22,5 +DA:23,0 +DA:24,0 +DA:25,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:29,0 +DA:30,0 +DA:32,0 +DA:34,5 +DA:35,5 +DA:36,5 +DA:37,5 +DA:38,5 +DA:40,5 +DA:41,5 +DA:42,0 +DA:44,0 +DA:45,0 +DA:46,0 +DA:47,0 +DA:48,0 +DA:49,0 +DA:50,0 +DA:51,0 +DA:53,0 +DA:55,5 +DA:56,0 +DA:57,0 +DA:58,0 +DA:59,0 +DA:60,0 +DA:61,5 +DA:62,5 +DA:63,5 +LF:48 +LH:23 +end_of_record +SF:solvers/minion/src/error.rs +FN:8,>::from +FN:47,>::from +FN:8,::fmt +FN:8,::fmt +FN:8,::fmt +FN:8,>::from +FN:31,::fmt +FN:8,::source +FN:8,>::from +FN:8,::source +FN:8,::source +FN:8,>::from +FN:47,>::from +FN:31,::fmt +FN:8,>::from +FN:47,>::from +FN:8,>::from +FN:31,::fmt +FNDA:0,>::from +FNDA:0,>::from +FNDA:0,::fmt +FNDA:0,::fmt +FNDA:0,::fmt +FNDA:0,>::from +FNDA:0,::fmt +FNDA:0,::source +FNDA:0,>::from +FNDA:0,::source +FNDA:0,::source +FNDA:0,>::from +FNDA:0,>::from +FNDA:0,::fmt +FNDA:0,>::from +FNDA:0,>::from +FNDA:0,>::from +FNDA:0,::fmt +FNF:18 +FNH:0 +BRF:0 +BRH:0 +DA:8,0 +DA:31,0 +DA:47,0 +DA:48,0 +DA:50,0 +DA:51,0 +DA:53,0 +LF:7 +LH:0 +end_of_record +SF:conjure_oxide/src/utils/misc.rs +FN:5,conjure_oxide::utils::misc::to_set::<_> +FN:5,conjure_oxide::utils::misc::to_set::<_> +FN:5,conjure_oxide::utils::misc::to_set::<_> +FNDA:0,conjure_oxide::utils::misc::to_set::<_> +FNDA:0,conjure_oxide::utils::misc::to_set::<_> +FNDA:0,conjure_oxide::utils::misc::to_set::<_> +FNF:3 +FNH:0 +BRF:0 +BRH:0 +DA:5,0 +DA:6,0 +DA:7,0 +DA:8,0 +DA:9,0 +DA:10,0 +DA:11,0 +LF:7 +LH:0 +end_of_record +SF:crates/conjure_core/src/rule_engine/rule_set.rs +FN:140,::eq +FN:47,::get_rules +FN:89,::resolve_rules +FN:159,::fmt::{closure#0} +FN:29,::new +FN:89,::resolve_rules +FN:159,::fmt::{closure#0} +FN:82,::with_dependencies +FN:154,::fmt +FN:114,::resolve_dependencies +FN:114,::resolve_dependencies +FN:148,::hash::<_> +FN:65,::get_dependencies +FN:65,::get_dependencies +FN:29,::new +FN:47,::get_rules +FN:82,::with_dependencies +FN:114,::resolve_dependencies +FN:154,::fmt +FN:154,::fmt +FN:140,::eq +FN:47,::get_rules +FN:148,::hash:: +FN:29,::new +FN:140,::eq +FN:148,::hash:: +FN:89,::resolve_rules +FN:159,::fmt::{closure#0} +FN:82,::with_dependencies +FN:65,::get_dependencies +FNDA:0,::eq +FNDA:1,::get_rules +FNDA:0,::resolve_rules +FNDA:0,::fmt::{closure#0} +FNDA:0,::new +FNDA:0,::resolve_rules +FNDA:0,::fmt::{closure#0} +FNDA:0,::with_dependencies +FNDA:0,::fmt +FNDA:0,::resolve_dependencies +FNDA:1,::resolve_dependencies +FNDA:0,::hash::<_> +FNDA:0,::get_dependencies +FNDA:1,::get_dependencies +FNDA:0,::new +FNDA:0,::get_rules +FNDA:1,::with_dependencies +FNDA:0,::resolve_dependencies +FNDA:0,::fmt +FNDA:0,::fmt +FNDA:0,::eq +FNDA:0,::get_rules +FNDA:1,::hash:: +FNDA:0,::new +FNDA:0,::eq +FNDA:0,::hash:: +FNDA:1,::resolve_rules +FNDA:0,::fmt::{closure#0} +FNDA:0,::with_dependencies +FNDA:0,::get_dependencies +FNF:30 +FNH:6 +BRF:0 +BRH:0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:34,0 +DA:35,0 +DA:36,0 +DA:37,0 +DA:38,0 +DA:39,0 +DA:40,0 +DA:41,0 +DA:42,0 +DA:43,0 +DA:47,495 +DA:48,495 +DA:50,165 +DA:51,165 +DA:52,165 +DA:53,165 +DA:54,165 +DA:55,165 +DA:56,165 +DA:58,330 +DA:60,495 +DA:65,360 +DA:66,360 +DA:68,120 +DA:69,120 +DA:70,120 +DA:71,120 +DA:72,120 +DA:73,120 +DA:74,120 +DA:76,240 +DA:78,360 +DA:82,180 +DA:83,180 +DA:84,180 +DA:85,180 +DA:86,180 +DA:89,165 +DA:90,165 +DA:92,4785 +DA:93,4620 +DA:94,4620 +DA:96,7695 +DA:97,4620 +DA:98,1545 +DA:99,1545 +DA:100,1545 +DA:101,3075 +DA:104,4620 +DA:105,1545 +DA:106,3075 +DA:109,165 +DA:110,165 +DA:114,180 +DA:115,180 +DA:117,240 +DA:118,60 +DA:120,0 +DA:121,0 +DA:122,0 +DA:125,60 +DA:126,60 +DA:127,60 +DA:128,60 +DA:129,60 +DA:130,60 +DA:135,180 +DA:136,180 +DA:140,0 +DA:141,0 +DA:142,0 +DA:148,960 +DA:149,960 +DA:150,960 +DA:154,0 +DA:155,0 +DA:156,0 +DA:157,0 +DA:158,0 +DA:159,0 +DA:160,0 +DA:161,0 +DA:162,0 +DA:163,0 +DA:164,0 +DA:165,0 +DA:166,0 +DA:167,0 +DA:168,0 +DA:169,0 +DA:170,0 +DA:171,0 +DA:172,0 +LF:98 +LH:58 +end_of_record +SF:crates/conjure_core/src/rules/base.rs +FN:349,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_AND::__typecheck +FN:389,conjure_core::rules::base::evaluate_constant_not +FN:108,conjure_core::rules::base::CONJURE_GEN_RULE_SUM_CONSTANTS::__typecheck::{closure#0} +FN:483,conjure_core::rules::base::CONJURE_GEN_RULE_DISTRIBUTE_OR_OVER_AND::__typecheck::{closure#0}::{closure#0} +FN:28,conjure_core::rules::base::remove_nothings::remove_nothings +FN:291,conjure_core::rules::base::remove_trivial_or +FN:86,conjure_core::rules::base::CONJURE_GEN_RULE_EMPTY_TO_NOTHING::__typecheck +FN:483,conjure_core::rules::base::CONJURE_GEN_RULE_DISTRIBUTE_OR_OVER_AND::__typecheck +FN:189,conjure_core::rules::base::unwrap_nested_or +FN:290,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_OR::__typecheck::{closure#0} +FN:254,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_DOUBLE_NEGATION::__typecheck +FN:389,conjure_core::rules::base::evaluate_constant_not +FN:290,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_OR::__typecheck::{closure#0}::{closure#0} +FN:86,conjure_core::rules::base::CONJURE_GEN_RULE_EMPTY_TO_NOTHING::__typecheck::{closure#0} +FN:28,conjure_core::rules::base::remove_nothings::remove_nothings +FN:152,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_152_0 +FN:188,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_OR::__typecheck::{closure#0} +FN:109,conjure_core::rules::base::sum_constants +FN:385,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_385_0 +FN:26,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_NOTHINGS::__typecheck::{closure#0}::{closure#0} +FN:155,conjure_core::rules::base::CONJURE_GEN_RULE_FLATTEN_NESTED_SUM::__typecheck::{closure#0} +FN:290,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_OR::__typecheck::{closure#0} +FN:424,conjure_core::rules::base::CONJURE_GEN_RULE_MIN_TO_VAR::__typecheck::{closure#0}::{closure#0} +FN:218,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_218_0 +FN:421,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_421_0 +FN:141,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_SUM::__typecheck::{closure#0}::{closure#0} +FN:254,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_DOUBLE_NEGATION::__typecheck::{closure#0} +FN:290,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_OR::__typecheck +FN:310,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_OR::__typecheck::{closure#0}::{closure#0} +FN:271,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_AND::__typecheck::{closure#0}::{closure#0} +FN:484,conjure_core::rules::base::distribute_or_over_and +FN:86,conjure_core::rules::base::CONJURE_GEN_RULE_EMPTY_TO_NOTHING::__typecheck::{closure#0}::{closure#0} +FN:15,conjure_core::rules::base::CONJURE_GEN_RULE_SET_BASE::__typecheck::{closure#0} +FN:310,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_OR::__typecheck +FN:388,conjure_core::rules::base::CONJURE_GEN_RULE_EVALUATE_CONSTANT_NOT::__typecheck +FN:27,conjure_core::rules::base::remove_nothings +FN:480,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_480_0 +FN:388,conjure_core::rules::base::CONJURE_GEN_RULE_EVALUATE_CONSTANT_NOT::__typecheck::{closure#0}::{closure#0} +FN:271,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_AND::__typecheck::{closure#0} +FN:388,conjure_core::rules::base::CONJURE_GEN_RULE_EVALUATE_CONSTANT_NOT::__typecheck::{closure#0} +FN:15,conjure_core::rules::base::CONJURE_GEN_RULE_SET_BASE::__typecheck +FN:86,conjure_core::rules::base::CONJURE_GEN_RULE_EMPTY_TO_NOTHING::__typecheck +FN:189,conjure_core::rules::base::unwrap_nested_or +FN:483,conjure_core::rules::base::CONJURE_GEN_RULE_DISTRIBUTE_OR_OVER_AND::__typecheck::{closure#0} +FN:349,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_AND::__typecheck::{closure#0} +FN:311,conjure_core::rules::base::remove_constants_from_or +FN:26,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_NOTHINGS::__typecheck +FN:307,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_307_0 +FN:86,conjure_core::rules::base::CONJURE_GEN_RULE_EMPTY_TO_NOTHING::__typecheck::{closure#0}::{closure#0} +FN:221,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_AND::__typecheck::{closure#0} +FN:108,conjure_core::rules::base::CONJURE_GEN_RULE_SUM_CONSTANTS::__typecheck::{closure#0}::{closure#0} +FN:483,conjure_core::rules::base::CONJURE_GEN_RULE_DISTRIBUTE_OR_OVER_AND::__typecheck::{closure#0} +FN:310,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_OR::__typecheck::{closure#0} +FN:141,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_SUM::__typecheck::{closure#0}::{closure#0} +FN:310,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_OR::__typecheck::{closure#0}::{closure#0} +FN:349,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_AND::__typecheck::{closure#0}::{closure#0} +FN:141,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_SUM::__typecheck::{closure#0} +FN:138,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_138_0 +FN:424,conjure_core::rules::base::CONJURE_GEN_RULE_MIN_TO_VAR::__typecheck::{closure#0} +FN:86,conjure_core::rules::base::CONJURE_GEN_RULE_EMPTY_TO_NOTHING::__typecheck::{closure#0} +FN:254,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_DOUBLE_NEGATION::__typecheck::{closure#0}::{closure#0} +FN:424,conjure_core::rules::base::CONJURE_GEN_RULE_MIN_TO_VAR::__typecheck::{closure#0} +FN:271,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_AND::__typecheck::{closure#0}::{closure#0} +FN:483,conjure_core::rules::base::CONJURE_GEN_RULE_DISTRIBUTE_OR_OVER_AND::__typecheck +FN:424,conjure_core::rules::base::CONJURE_GEN_RULE_MIN_TO_VAR::__typecheck::{closure#0}::{closure#0} +FN:425,conjure_core::rules::base::min_to_var +FN:349,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_AND::__typecheck::{closure#0} +FN:23,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_23_0 +FN:290,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_OR::__typecheck::{closure#0}::{closure#0} +FN:255,conjure_core::rules::base::remove_double_negation +FN:26,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_NOTHINGS::__typecheck +FN:188,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_OR::__typecheck::{closure#0} +FN:188,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_OR::__typecheck::{closure#0}::{closure#0} +FN:48,conjure_core::rules::base::remove_nothings::get_lhs_rhs +FN:254,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_DOUBLE_NEGATION::__typecheck +FN:290,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_OR::__typecheck +FN:155,conjure_core::rules::base::CONJURE_GEN_RULE_FLATTEN_NESTED_SUM::__typecheck +FN:425,conjure_core::rules::base::min_to_var +FN:86,conjure_core::rules::base::CONJURE_GEN_RULE_EMPTY_TO_NOTHING::__typecheck +FN:188,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_OR::__typecheck +FN:15,conjure_core::rules::base::CONJURE_GEN_RULE_SET_BASE::__typecheck::{closure#0} +FN:424,conjure_core::rules::base::CONJURE_GEN_RULE_MIN_TO_VAR::__typecheck +FN:483,conjure_core::rules::base::CONJURE_GEN_RULE_DISTRIBUTE_OR_OVER_AND::__typecheck::{closure#0}::{closure#0} +FN:485,conjure_core::rules::base::distribute_or_over_and::find_and +FN:142,conjure_core::rules::base::unwrap_sum +FN:350,conjure_core::rules::base::remove_constants_from_and +FN:141,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_SUM::__typecheck +FN:156,conjure_core::rules::base::flatten_nested_sum +FN:272,conjure_core::rules::base::remove_trivial_and +FN:311,conjure_core::rules::base::remove_constants_from_or +FN:388,conjure_core::rules::base::CONJURE_GEN_RULE_EVALUATE_CONSTANT_NOT::__typecheck::{closure#0}::{closure#0} +FN:141,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_SUM::__typecheck::{closure#0} +FN:222,conjure_core::rules::base::unwrap_nested_and +FN:483,conjure_core::rules::base::CONJURE_GEN_RULE_DISTRIBUTE_OR_OVER_AND::__typecheck::{closure#0} +FN:15,conjure_core::rules::base::CONJURE_GEN_RULE_SET_BASE::__typecheck::{closure#0} +FN:388,conjure_core::rules::base::CONJURE_GEN_RULE_EVALUATE_CONSTANT_NOT::__typecheck +FN:311,conjure_core::rules::base::remove_constants_from_or +FN:48,conjure_core::rules::base::remove_nothings::get_lhs_rhs +FN:424,conjure_core::rules::base::CONJURE_GEN_RULE_MIN_TO_VAR::__typecheck::{closure#0}::{closure#0} +FN:105,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_105_0 +FN:254,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_DOUBLE_NEGATION::__typecheck::{closure#0} +FN:349,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_AND::__typecheck +FN:346,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_346_0 +FN:291,conjure_core::rules::base::remove_trivial_or +FN:483,conjure_core::rules::base::CONJURE_GEN_RULE_DISTRIBUTE_OR_OVER_AND::__typecheck +FN:272,conjure_core::rules::base::remove_trivial_and +FN:86,conjure_core::rules::base::CONJURE_GEN_RULE_EMPTY_TO_NOTHING::__typecheck::{closure#0} +FN:255,conjure_core::rules::base::remove_double_negation +FN:15,conjure_core::rules::base::CONJURE_GEN_RULE_SET_BASE::__typecheck::{closure#0}::{closure#0} +FN:271,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_AND::__typecheck::{closure#0} +FN:425,conjure_core::rules::base::min_to_var +FN:388,conjure_core::rules::base::CONJURE_GEN_RULE_EVALUATE_CONSTANT_NOT::__typecheck::{closure#0}::{closure#0} +FN:188,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_OR::__typecheck +FN:155,conjure_core::rules::base::CONJURE_GEN_RULE_FLATTEN_NESTED_SUM::__typecheck::{closure#0} +FN:254,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_DOUBLE_NEGATION::__typecheck::{closure#0}::{closure#0} +FN:221,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_AND::__typecheck::{closure#0}::{closure#0} +FN:142,conjure_core::rules::base::unwrap_sum +FN:142,conjure_core::rules::base::unwrap_sum +FN:222,conjure_core::rules::base::unwrap_nested_and +FN:349,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_AND::__typecheck::{closure#0}::{closure#0} +FN:271,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_AND::__typecheck::{closure#0} +FN:290,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_OR::__typecheck +FN:254,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_DOUBLE_NEGATION::__typecheck::{closure#0}::{closure#0} +FN:15,conjure_core::rules::base::CONJURE_GEN_RULE_SET_BASE::__typecheck +FN:287,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_287_0 +FN:290,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_OR::__typecheck::{closure#0} +FN:83,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_83_0 +FN:271,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_AND::__typecheck +FN:141,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_SUM::__typecheck::{closure#0} +FN:26,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_NOTHINGS::__typecheck::{closure#0} +FN:108,conjure_core::rules::base::CONJURE_GEN_RULE_SUM_CONSTANTS::__typecheck +FN:251,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_251_0 +FN:188,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_OR::__typecheck::{closure#0}::{closure#0} +FN:290,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_OR::__typecheck::{closure#0}::{closure#0} +FN:155,conjure_core::rules::base::CONJURE_GEN_RULE_FLATTEN_NESTED_SUM::__typecheck +FN:310,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_OR::__typecheck::{closure#0} +FN:15,conjure_core::rules::base::CONJURE_GEN_RULE_SET_BASE::__typecheck +FN:108,conjure_core::rules::base::CONJURE_GEN_RULE_SUM_CONSTANTS::__typecheck::{closure#0} +FN:15,conjure_core::rules::base::CONJURE_GEN_RULE_SET_BASE::__typecheck::{closure#0}::{closure#0} +FN:141,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_SUM::__typecheck::{closure#0}::{closure#0} +FN:388,conjure_core::rules::base::CONJURE_GEN_RULE_EVALUATE_CONSTANT_NOT::__typecheck::{closure#0} +FN:222,conjure_core::rules::base::unwrap_nested_and +FN:310,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_OR::__typecheck +FN:221,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_AND::__typecheck +FN:155,conjure_core::rules::base::CONJURE_GEN_RULE_FLATTEN_NESTED_SUM::__typecheck::{closure#0}::{closure#0} +FN:108,conjure_core::rules::base::CONJURE_GEN_RULE_SUM_CONSTANTS::__typecheck +FN:268,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_268_0 +FN:350,conjure_core::rules::base::remove_constants_from_and +FN:15,conjure_core::rules::base::CONJURE_GEN_RULE_SET_BASE::__typecheck::{closure#0}::{closure#0} +FN:350,conjure_core::rules::base::remove_constants_from_and +FN:254,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_DOUBLE_NEGATION::__typecheck +FN:291,conjure_core::rules::base::remove_trivial_or +FN:310,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_OR::__typecheck +FN:388,conjure_core::rules::base::CONJURE_GEN_RULE_EVALUATE_CONSTANT_NOT::__typecheck::{closure#0} +FN:424,conjure_core::rules::base::CONJURE_GEN_RULE_MIN_TO_VAR::__typecheck +FN:221,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_AND::__typecheck +FN:271,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_AND::__typecheck +FN:141,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_SUM::__typecheck +FN:185,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_185_0 +FN:254,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_DOUBLE_NEGATION::__typecheck::{closure#0} +FN:272,conjure_core::rules::base::remove_trivial_and +FN:26,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_NOTHINGS::__typecheck::{closure#0} +FN:155,conjure_core::rules::base::CONJURE_GEN_RULE_FLATTEN_NESTED_SUM::__typecheck::{closure#0}::{closure#0} +FN:108,conjure_core::rules::base::CONJURE_GEN_RULE_SUM_CONSTANTS::__typecheck::{closure#0}::{closure#0} +FN:483,conjure_core::rules::base::CONJURE_GEN_RULE_DISTRIBUTE_OR_OVER_AND::__typecheck::{closure#0}::{closure#0} +FN:26,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_NOTHINGS::__typecheck::{closure#0}::{closure#0} +FN:138,rust_out::main +FN:271,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_AND::__typecheck +FN:28,conjure_core::rules::base::remove_nothings::remove_nothings +FN:155,conjure_core::rules::base::CONJURE_GEN_RULE_FLATTEN_NESTED_SUM::__typecheck +FN:485,conjure_core::rules::base::distribute_or_over_and::find_and +FN:349,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_AND::__typecheck::{closure#0} +FN:189,conjure_core::rules::base::unwrap_nested_or +FN:156,conjure_core::rules::base::flatten_nested_sum +FN:221,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_AND::__typecheck::{closure#0} +FN:310,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_OR::__typecheck::{closure#0}::{closure#0} +FN:310,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_OR::__typecheck::{closure#0} +FN:349,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_AND::__typecheck +FN:388,conjure_core::rules::base::CONJURE_GEN_RULE_EVALUATE_CONSTANT_NOT::__typecheck +FN:424,conjure_core::rules::base::CONJURE_GEN_RULE_MIN_TO_VAR::__typecheck::{closure#0} +FN:27,conjure_core::rules::base::remove_nothings +FN:108,conjure_core::rules::base::CONJURE_GEN_RULE_SUM_CONSTANTS::__typecheck +FN:484,conjure_core::rules::base::distribute_or_over_and +FN:188,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_OR::__typecheck +FN:109,conjure_core::rules::base::sum_constants +FN:48,conjure_core::rules::base::remove_nothings::get_lhs_rhs +FN:87,conjure_core::rules::base::empty_to_nothing +FN:155,conjure_core::rules::base::CONJURE_GEN_RULE_FLATTEN_NESTED_SUM::__typecheck::{closure#0}::{closure#0} +FN:389,conjure_core::rules::base::evaluate_constant_not +FN:484,conjure_core::rules::base::distribute_or_over_and +FN:26,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_NOTHINGS::__typecheck +FN:188,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_OR::__typecheck::{closure#0} +FN:255,conjure_core::rules::base::remove_double_negation +FN:87,conjure_core::rules::base::empty_to_nothing +FN:221,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_AND::__typecheck +FN:271,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_AND::__typecheck::{closure#0}::{closure#0} +FN:349,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_AND::__typecheck::{closure#0}::{closure#0} +FN:485,conjure_core::rules::base::distribute_or_over_and::find_and +FN:221,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_AND::__typecheck::{closure#0}::{closure#0} +FN:26,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_NOTHINGS::__typecheck::{closure#0} +FN:108,conjure_core::rules::base::CONJURE_GEN_RULE_SUM_CONSTANTS::__typecheck::{closure#0} +FN:108,conjure_core::rules::base::CONJURE_GEN_RULE_SUM_CONSTANTS::__typecheck::{closure#0}::{closure#0} +FN:424,conjure_core::rules::base::CONJURE_GEN_RULE_MIN_TO_VAR::__typecheck +FN:26,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_NOTHINGS::__typecheck::{closure#0}::{closure#0} +FN:156,conjure_core::rules::base::flatten_nested_sum +FN:86,conjure_core::rules::base::CONJURE_GEN_RULE_EMPTY_TO_NOTHING::__typecheck::{closure#0}::{closure#0} +FN:188,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_OR::__typecheck::{closure#0}::{closure#0} +FN:221,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_AND::__typecheck::{closure#0} +FN:221,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_AND::__typecheck::{closure#0}::{closure#0} +FN:27,conjure_core::rules::base::remove_nothings +FN:87,conjure_core::rules::base::empty_to_nothing +FN:141,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_SUM::__typecheck +FN:155,conjure_core::rules::base::CONJURE_GEN_RULE_FLATTEN_NESTED_SUM::__typecheck::{closure#0} +FN:109,conjure_core::rules::base::sum_constants +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_AND::__typecheck +FNDA:0,conjure_core::rules::base::evaluate_constant_not +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_SUM_CONSTANTS::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_DISTRIBUTE_OR_OVER_AND::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::remove_nothings::remove_nothings +FNDA:1,conjure_core::rules::base::remove_trivial_or +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_EMPTY_TO_NOTHING::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_DISTRIBUTE_OR_OVER_AND::__typecheck +FNDA:0,conjure_core::rules::base::unwrap_nested_or +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_OR::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_DOUBLE_NEGATION::__typecheck +FNDA:1,conjure_core::rules::base::evaluate_constant_not +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_OR::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_EMPTY_TO_NOTHING::__typecheck::{closure#0} +FNDA:1,conjure_core::rules::base::remove_nothings::remove_nothings +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_152_0 +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_OR::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::sum_constants +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_385_0 +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_NOTHINGS::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_FLATTEN_NESTED_SUM::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_OR::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_MIN_TO_VAR::__typecheck::{closure#0}::{closure#0} +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_218_0 +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_421_0 +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_SUM::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_DOUBLE_NEGATION::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_OR::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_OR::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_AND::__typecheck::{closure#0}::{closure#0} +FNDA:1,conjure_core::rules::base::distribute_or_over_and +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_EMPTY_TO_NOTHING::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_SET_BASE::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_OR::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_EVALUATE_CONSTANT_NOT::__typecheck +FNDA:1,conjure_core::rules::base::remove_nothings +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_480_0 +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_EVALUATE_CONSTANT_NOT::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_AND::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_EVALUATE_CONSTANT_NOT::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_SET_BASE::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_EMPTY_TO_NOTHING::__typecheck +FNDA:1,conjure_core::rules::base::unwrap_nested_or +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_DISTRIBUTE_OR_OVER_AND::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_AND::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::remove_constants_from_or +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_NOTHINGS::__typecheck +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_307_0 +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_EMPTY_TO_NOTHING::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_AND::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_SUM_CONSTANTS::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_DISTRIBUTE_OR_OVER_AND::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_OR::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_SUM::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_OR::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_AND::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_SUM::__typecheck::{closure#0} +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_138_0 +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_MIN_TO_VAR::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_EMPTY_TO_NOTHING::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_DOUBLE_NEGATION::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_MIN_TO_VAR::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_AND::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_DISTRIBUTE_OR_OVER_AND::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_MIN_TO_VAR::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::min_to_var +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_AND::__typecheck::{closure#0} +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_23_0 +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_OR::__typecheck::{closure#0}::{closure#0} +FNDA:1,conjure_core::rules::base::remove_double_negation +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_NOTHINGS::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_OR::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_OR::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::remove_nothings::get_lhs_rhs +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_DOUBLE_NEGATION::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_OR::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_FLATTEN_NESTED_SUM::__typecheck +FNDA:0,conjure_core::rules::base::min_to_var +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_EMPTY_TO_NOTHING::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_OR::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_SET_BASE::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_MIN_TO_VAR::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_DISTRIBUTE_OR_OVER_AND::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::distribute_or_over_and::find_and +FNDA:0,conjure_core::rules::base::unwrap_sum +FNDA:0,conjure_core::rules::base::remove_constants_from_and +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_SUM::__typecheck +FNDA:0,conjure_core::rules::base::flatten_nested_sum +FNDA:1,conjure_core::rules::base::remove_trivial_and +FNDA:0,conjure_core::rules::base::remove_constants_from_or +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_EVALUATE_CONSTANT_NOT::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_SUM::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::unwrap_nested_and +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_DISTRIBUTE_OR_OVER_AND::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_SET_BASE::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_EVALUATE_CONSTANT_NOT::__typecheck +FNDA:1,conjure_core::rules::base::remove_constants_from_or +FNDA:0,conjure_core::rules::base::remove_nothings::get_lhs_rhs +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_MIN_TO_VAR::__typecheck::{closure#0}::{closure#0} +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_105_0 +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_DOUBLE_NEGATION::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_AND::__typecheck +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_346_0 +FNDA:0,conjure_core::rules::base::remove_trivial_or +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_DISTRIBUTE_OR_OVER_AND::__typecheck +FNDA:0,conjure_core::rules::base::remove_trivial_and +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_EMPTY_TO_NOTHING::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::remove_double_negation +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_SET_BASE::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_AND::__typecheck::{closure#0} +FNDA:1,conjure_core::rules::base::min_to_var +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_EVALUATE_CONSTANT_NOT::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_OR::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_FLATTEN_NESTED_SUM::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_DOUBLE_NEGATION::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_AND::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::unwrap_sum +FNDA:1,conjure_core::rules::base::unwrap_sum +FNDA:0,conjure_core::rules::base::unwrap_nested_and +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_AND::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_AND::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_OR::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_DOUBLE_NEGATION::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_SET_BASE::__typecheck +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_287_0 +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_OR::__typecheck::{closure#0} +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_83_0 +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_AND::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_SUM::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_NOTHINGS::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_SUM_CONSTANTS::__typecheck +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_251_0 +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_OR::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_OR::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_FLATTEN_NESTED_SUM::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_OR::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_SET_BASE::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_SUM_CONSTANTS::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_SET_BASE::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_SUM::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_EVALUATE_CONSTANT_NOT::__typecheck::{closure#0} +FNDA:1,conjure_core::rules::base::unwrap_nested_and +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_OR::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_AND::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_FLATTEN_NESTED_SUM::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_SUM_CONSTANTS::__typecheck +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_268_0 +FNDA:1,conjure_core::rules::base::remove_constants_from_and +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_SET_BASE::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::remove_constants_from_and +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_DOUBLE_NEGATION::__typecheck +FNDA:0,conjure_core::rules::base::remove_trivial_or +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_OR::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_EVALUATE_CONSTANT_NOT::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_MIN_TO_VAR::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_AND::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_AND::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_SUM::__typecheck +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_base_rs_185_0 +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_DOUBLE_NEGATION::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::remove_trivial_and +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_NOTHINGS::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_FLATTEN_NESTED_SUM::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_SUM_CONSTANTS::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_DISTRIBUTE_OR_OVER_AND::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_NOTHINGS::__typecheck::{closure#0}::{closure#0} +FNDA:1,rust_out::main +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_AND::__typecheck +FNDA:0,conjure_core::rules::base::remove_nothings::remove_nothings +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_FLATTEN_NESTED_SUM::__typecheck +FNDA:1,conjure_core::rules::base::distribute_or_over_and::find_and +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_AND::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::unwrap_nested_or +FNDA:0,conjure_core::rules::base::flatten_nested_sum +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_AND::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_OR::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_OR::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_AND::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_EVALUATE_CONSTANT_NOT::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_MIN_TO_VAR::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::remove_nothings +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_SUM_CONSTANTS::__typecheck +FNDA:0,conjure_core::rules::base::distribute_or_over_and +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_OR::__typecheck +FNDA:0,conjure_core::rules::base::sum_constants +FNDA:0,conjure_core::rules::base::remove_nothings::get_lhs_rhs +FNDA:0,conjure_core::rules::base::empty_to_nothing +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_FLATTEN_NESTED_SUM::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::evaluate_constant_not +FNDA:0,conjure_core::rules::base::distribute_or_over_and +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_NOTHINGS::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_OR::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::remove_double_negation +FNDA:1,conjure_core::rules::base::empty_to_nothing +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_AND::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_TRIVIAL_AND::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_CONSTANTS_FROM_AND::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::distribute_or_over_and::find_and +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_AND::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_NOTHINGS::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_SUM_CONSTANTS::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_SUM_CONSTANTS::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_MIN_TO_VAR::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_REMOVE_NOTHINGS::__typecheck::{closure#0}::{closure#0} +FNDA:1,conjure_core::rules::base::flatten_nested_sum +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_EMPTY_TO_NOTHING::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_OR::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_AND::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_NESTED_AND::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::base::remove_nothings +FNDA:0,conjure_core::rules::base::empty_to_nothing +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_UNWRAP_SUM::__typecheck +FNDA:0,conjure_core::rules::base::CONJURE_GEN_RULE_FLATTEN_NESTED_SUM::__typecheck::{closure#0} +FNDA:1,conjure_core::rules::base::sum_constants +FNF:214 +FNH:33 +BRF:0 +BRH:0 +DA:15,0 +DA:23,1 +DA:24,1 +DA:25,1 +DA:26,0 +DA:27,29610 +DA:28,29610 +DA:29,29610 +DA:30,29610 +DA:32,62775 +DA:33,33165 +DA:34,0 +DA:35,0 +DA:36,0 +DA:37,33165 +DA:41,29610 +DA:42,0 +DA:44,29610 +DA:46,29610 +DA:48,0 +DA:49,0 +DA:50,0 +DA:51,0 +DA:52,0 +DA:53,0 +DA:54,0 +DA:55,0 +DA:56,0 +DA:58,29610 +DA:60,0 +DA:61,0 +DA:62,0 +DA:63,0 +DA:64,0 +DA:65,0 +DA:66,0 +DA:68,0 +DA:69,0 +DA:70,0 +DA:72,0 +DA:73,0 +DA:74,0 +DA:76,0 +DA:78,29610 +DA:83,1 +DA:84,1 +DA:85,1 +DA:86,0 +DA:87,29610 +DA:88,29610 +DA:90,18630 +DA:93,10980 +DA:94,0 +DA:96,10980 +DA:100,29610 +DA:105,1 +DA:106,1 +DA:107,1 +DA:108,0 +DA:109,29655 +DA:110,29655 +DA:111,60 +DA:112,60 +DA:113,60 +DA:114,60 +DA:115,225 +DA:116,120 +DA:117,120 +DA:118,120 +DA:119,120 +DA:120,120 +DA:121,45 +DA:124,60 +DA:125,15 +DA:126,45 +DA:127,45 +DA:128,45 +DA:129,45 +DA:131,29595 +DA:133,29655 +DA:138,1 +DA:139,1 +DA:140,1 +DA:141,0 +DA:142,29640 +DA:143,45 +DA:144,45 +DA:145,29610 +DA:147,29640 +DA:152,1 +DA:153,1 +DA:154,1 +DA:155,0 +DA:156,29610 +DA:157,29610 +DA:158,15 +DA:159,15 +DA:160,15 +DA:161,45 +DA:162,30 +DA:163,15 +DA:164,15 +DA:165,45 +DA:166,30 +DA:167,30 +DA:169,15 +DA:172,15 +DA:173,0 +DA:174,15 +DA:175,15 +DA:177,29595 +DA:179,29610 +DA:185,1 +DA:186,1 +DA:187,1 +DA:188,0 +DA:189,29640 +DA:190,29640 +DA:191,2205 +DA:192,2205 +DA:193,2205 +DA:194,6615 +DA:195,4410 +DA:196,15 +DA:197,15 +DA:198,45 +DA:199,30 +DA:200,30 +DA:202,4395 +DA:205,2205 +DA:206,2190 +DA:207,15 +DA:208,15 +DA:210,27435 +DA:212,29640 +DA:218,1 +DA:219,1 +DA:220,1 +DA:221,0 +DA:222,29640 +DA:223,29640 +DA:224,1560 +DA:225,1560 +DA:226,1560 +DA:227,9480 +DA:228,7920 +DA:229,345 +DA:230,345 +DA:231,1110 +DA:232,765 +DA:233,765 +DA:235,7575 +DA:238,1560 +DA:239,1215 +DA:240,345 +DA:241,345 +DA:243,28080 +DA:245,29640 +DA:251,1 +DA:252,1 +DA:253,1 +DA:254,0 +DA:255,29625 +DA:256,29625 +DA:257,15 +DA:258,15 +DA:259,0 +DA:261,29610 +DA:263,29625 +DA:268,1 +DA:269,1 +DA:270,1 +DA:271,0 +DA:272,29625 +DA:273,29625 +DA:274,1545 +DA:275,1545 +DA:276,15 +DA:277,1530 +DA:278,1530 +DA:280,28080 +DA:282,29625 +DA:287,1 +DA:288,1 +DA:289,1 +DA:290,0 +DA:291,29625 +DA:292,29625 +DA:293,2190 +DA:294,2190 +DA:295,15 +DA:296,2175 +DA:297,2175 +DA:299,27435 +DA:301,29625 +DA:307,1 +DA:308,1 +DA:309,1 +DA:310,0 +DA:311,29640 +DA:312,29640 +DA:313,2205 +DA:314,2205 +DA:315,2205 +DA:316,6585 +DA:317,15 +DA:318,15 +DA:319,15 +DA:321,15 +DA:322,15 +DA:323,15 +DA:324,15 +DA:325,0 +DA:326,0 +DA:327,0 +DA:328,0 +DA:330,4380 +DA:333,2190 +DA:334,2190 +DA:335,0 +DA:336,0 +DA:338,27435 +DA:340,29640 +DA:346,1 +DA:347,1 +DA:348,1 +DA:349,0 +DA:350,29640 +DA:351,29640 +DA:352,1560 +DA:353,1560 +DA:354,1560 +DA:355,9465 +DA:356,30 +DA:357,30 +DA:358,30 +DA:360,15 +DA:361,15 +DA:362,15 +DA:363,15 +DA:364,15 +DA:365,15 +DA:366,15 +DA:367,15 +DA:369,7890 +DA:372,1545 +DA:373,1545 +DA:374,0 +DA:375,0 +DA:377,28080 +DA:379,29640 +DA:385,1 +DA:386,1 +DA:387,1 +DA:388,0 +DA:389,29610 +DA:390,29610 +DA:391,0 +DA:392,0 +DA:393,0 +DA:394,0 +DA:395,0 +DA:396,0 +DA:398,29610 +DA:400,29610 +DA:421,1 +DA:422,1 +DA:423,1 +DA:424,0 +DA:425,29610 +DA:426,29610 +DA:427,75 +DA:428,75 +DA:429,75 +DA:430,75 +DA:431,75 +DA:432,225 +DA:433,150 +DA:434,150 +DA:435,150 +DA:436,150 +DA:437,150 +DA:438,150 +DA:439,150 +DA:440,150 +DA:441,150 +DA:442,150 +DA:443,150 +DA:444,150 +DA:445,150 +DA:446,150 +DA:447,150 +DA:448,150 +DA:449,150 +DA:450,150 +DA:451,150 +DA:452,150 +DA:453,150 +DA:454,150 +DA:455,75 +DA:456,75 +DA:457,75 +DA:458,75 +DA:459,75 +DA:460,75 +DA:461,75 +DA:462,75 +DA:463,75 +DA:464,75 +DA:465,75 +DA:466,75 +DA:467,75 +DA:468,75 +DA:469,75 +DA:470,75 +DA:472,29535 +DA:474,29610 +DA:480,1 +DA:481,1 +DA:482,1 +DA:483,0 +DA:484,29625 +DA:485,29625 +DA:486,29625 +DA:487,29625 +DA:488,29625 +DA:489,29625 +DA:490,29625 +DA:491,29625 +DA:492,29625 +DA:493,29625 +DA:494,29625 +DA:495,29625 +DA:496,2190 +DA:497,240 +DA:498,240 +DA:499,240 +DA:500,240 +DA:501,240 +DA:502,240 +DA:503,240 +DA:505,720 +DA:507,480 +DA:508,480 +DA:509,480 +DA:512,240 +DA:513,240 +DA:514,240 +DA:515,240 +DA:517,0 +DA:520,1950 +DA:522,27435 +DA:524,29625 +LF:353 +LH:292 +end_of_record +SF:conjure_oxide/src/utils/testing.rs +FN:148,conjure_oxide::utils::testing::save_minion_solutions_json +FN:148,conjure_oxide::utils::testing::save_minion_solutions_json +FN:77,conjure_oxide::utils::testing::save_stats_json +FN:53,conjure_oxide::utils::testing::save_model_json +FN:148,conjure_oxide::utils::testing::save_minion_solutions_json +FN:95,conjure_oxide::utils::testing::read_model_json +FN:110,conjure_oxide::utils::testing::minion_solutions_from_json +FN:110,conjure_oxide::utils::testing::minion_solutions_from_json +FN:41,conjure_oxide::utils::testing::serialise_model +FN:173,conjure_oxide::utils::testing::read_minion_solutions_json +FN:20,conjure_oxide::utils::testing::assert_eq_any_order::<_> +FN:173,conjure_oxide::utils::testing::read_minion_solutions_json +FN:41,conjure_oxide::utils::testing::serialise_model +FN:41,conjure_oxide::utils::testing::serialise_model +FN:53,conjure_oxide::utils::testing::save_model_json +FN:110,conjure_oxide::utils::testing::minion_solutions_from_json +FN:95,conjure_oxide::utils::testing::read_model_json +FN:20,conjure_oxide::utils::testing::assert_eq_any_order::<_> +FN:173,conjure_oxide::utils::testing::read_minion_solutions_json +FN:95,conjure_oxide::utils::testing::read_model_json +FN:53,conjure_oxide::utils::testing::save_model_json +FN:20,conjure_oxide::utils::testing::assert_eq_any_order::<_> +FN:77,conjure_oxide::utils::testing::save_stats_json +FN:77,conjure_oxide::utils::testing::save_stats_json +FNDA:1,conjure_oxide::utils::testing::save_minion_solutions_json +FNDA:0,conjure_oxide::utils::testing::save_minion_solutions_json +FNDA:0,conjure_oxide::utils::testing::save_stats_json +FNDA:0,conjure_oxide::utils::testing::save_model_json +FNDA:0,conjure_oxide::utils::testing::save_minion_solutions_json +FNDA:1,conjure_oxide::utils::testing::read_model_json +FNDA:0,conjure_oxide::utils::testing::minion_solutions_from_json +FNDA:0,conjure_oxide::utils::testing::minion_solutions_from_json +FNDA:1,conjure_oxide::utils::testing::serialise_model +FNDA:1,conjure_oxide::utils::testing::read_minion_solutions_json +FNDA:0,conjure_oxide::utils::testing::assert_eq_any_order::<_> +FNDA:0,conjure_oxide::utils::testing::read_minion_solutions_json +FNDA:0,conjure_oxide::utils::testing::serialise_model +FNDA:0,conjure_oxide::utils::testing::serialise_model +FNDA:0,conjure_oxide::utils::testing::save_model_json +FNDA:0,conjure_oxide::utils::testing::minion_solutions_from_json +FNDA:0,conjure_oxide::utils::testing::read_model_json +FNDA:0,conjure_oxide::utils::testing::assert_eq_any_order::<_> +FNDA:0,conjure_oxide::utils::testing::read_minion_solutions_json +FNDA:0,conjure_oxide::utils::testing::read_model_json +FNDA:1,conjure_oxide::utils::testing::save_model_json +FNDA:0,conjure_oxide::utils::testing::assert_eq_any_order::<_> +FNDA:0,conjure_oxide::utils::testing::save_stats_json +FNDA:1,conjure_oxide::utils::testing::save_stats_json +FNF:24 +FNH:6 +BRF:0 +BRH:0 +DA:20,0 +DA:21,0 +DA:23,0 +DA:24,0 +DA:25,0 +DA:26,0 +DA:27,0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:35,0 +DA:36,0 +DA:37,0 +DA:39,0 +DA:41,90 +DA:45,90 +DA:48,90 +DA:50,90 +DA:51,90 +DA:53,90 +DA:54,90 +DA:55,90 +DA:56,90 +DA:57,90 +DA:58,90 +DA:59,90 +DA:60,90 +DA:62,90 +DA:63,90 +DA:64,90 +DA:65,90 +DA:67,90 +DA:68,0 +DA:69,0 +DA:70,0 +DA:71,0 +DA:72,90 +DA:74,90 +DA:75,90 +DA:77,45 +DA:78,45 +DA:79,45 +DA:80,45 +DA:81,45 +DA:82,45 +DA:83,45 +DA:84,45 +DA:87,45 +DA:89,45 +DA:90,45 +DA:92,45 +DA:93,45 +DA:95,90 +DA:96,90 +DA:97,90 +DA:98,90 +DA:99,90 +DA:100,90 +DA:101,90 +DA:102,90 +DA:103,90 +DA:105,90 +DA:107,90 +DA:108,90 +DA:110,0 +DA:111,0 +DA:112,0 +DA:113,0 +DA:115,0 +DA:116,0 +DA:117,0 +DA:119,0 +DA:121,0 +DA:122,0 +DA:123,0 +DA:124,0 +DA:125,0 +DA:127,0 +DA:128,0 +DA:129,0 +DA:130,0 +DA:131,0 +DA:132,0 +DA:133,0 +DA:135,0 +DA:136,0 +DA:139,0 +DA:142,0 +DA:145,0 +DA:146,0 +DA:148,45 +DA:149,45 +DA:150,45 +DA:151,45 +DA:152,45 +DA:153,45 +DA:154,45 +DA:156,45 +DA:158,45 +DA:159,45 +DA:160,45 +DA:161,45 +DA:163,45 +DA:164,0 +DA:165,0 +DA:166,0 +DA:167,0 +DA:168,45 +DA:170,45 +DA:171,45 +DA:173,45 +DA:174,45 +DA:175,45 +DA:176,45 +DA:177,45 +DA:178,45 +DA:179,45 +DA:181,45 +DA:182,45 +DA:184,45 +DA:185,45 +LF:123 +LH:73 +end_of_record +SF:crates/conjure_core/src/solver/mod.rs +FN:274,>::load_model +FN:120,::size_hint +FN:120,::get +FN:128,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:268,>::get_family +FN:121,::fmt +FN:120,::clone +FN:59,rust_out::main::_doctest_main_crates_conjure_core_src_solver_mod_rs_24_0::{closure#0} +FN:285,>::solve +FN:128,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:274,>::load_model +FN:128,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:257,>::new +FN:121,::fmt +FN:128,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:216,::init_solver +FN:257,>::new +FN:353,>::stats +FN:227,::add_adaptor_info_to_stats +FN:227,<_ as conjure_core::solver::SolverAdaptor>::add_adaptor_info_to_stats +FN:353,>::stats +FN:257,>::new +FN:128,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:227,<_ as conjure_core::solver::SolverAdaptor>::add_adaptor_info_to_stats +FN:128,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:128,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FN:120,::fmt +FN:128,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FN:120,::len +FN:128,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:216,<_ as conjure_core::solver::SolverAdaptor>::init_solver +FN:120,::size_hint +FN:274,>::load_model +FN:216,::init_solver +FN:216,<_ as conjure_core::solver::SolverAdaptor>::init_solver +FN:128,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:227,::add_adaptor_info_to_stats +FN:377,::fmt +FN:370,>::wall_time_s +FN:353,>::stats +FN:222,<_ as conjure_core::solver::SolverAdaptor>::get_name +FN:128,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FN:120,::nth +FN:274,>::load_model +FN:120,::nth +FN:128,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:257,>::new +FN:257,>::new +FN:285,>::solve +FN:257,>::new +FN:285,>::solve +FN:274,>::load_model +FN:120,::iter +FN:274,>::load_model +FN:119,::from_str +FN:370,>::wall_time_s +FN:120,::iter +FN:227,<_ as conjure_core::solver::SolverAdaptor>::add_adaptor_info_to_stats +FN:120,::get +FN:222,<_ as conjure_core::solver::SolverAdaptor>::get_name +FN:120,::next_back +FN:120,::len +FN:128,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:353,>::stats +FN:353,>::stats +FN:358,>::save_stats_to_context +FN:216,<_ as conjure_core::solver::SolverAdaptor>::init_solver +FN:377,::fmt +FN:119,::from_str +FN:120,::clone +FN:128,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:268,>::get_family +FN:120,::get +FN:358,>::save_stats_to_context +FN:268,>::get_family +FN:119,>::try_from +FN:120,::next_back +FN:119,::from_str +FN:120,::next +FN:120,::next +FN:318,>::solve_mut +FN:128,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:128,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:120,::clone +FN:120,::len +FN:227,::add_adaptor_info_to_stats +FN:120,::fmt +FN:120,::nth +FN:358,>::save_stats_to_context +FN:358,>::save_stats_to_context +FN:216,::init_solver +FN:120,::fmt +FN:318,>::solve_mut +FN:25,rust_out::main +FN:128,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:120,::size_hint +FN:121,::fmt +FN:128,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:222,<_ as conjure_core::solver::SolverAdaptor>::get_name +FN:25,rust_out::main::_doctest_main_crates_conjure_core_src_solver_mod_rs_24_0 +FN:120,::next +FN:377,::fmt +FN:370,>::wall_time_s +FN:285,>::solve +FN:128,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:119,>::try_from +FN:128,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:285,>::solve +FN:285,>::solve +FN:120,::next_back +FN:120,::iter +FN:119,>::try_from +FN:128,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:358,>::save_stats_to_context +FN:318,>::solve_mut +FNDA:1,>::load_model +FNDA:0,::size_hint +FNDA:0,::get +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:0,>::get_family +FNDA:0,::fmt +FNDA:0,::clone +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_solver_mod_rs_24_0::{closure#0} +FNDA:0,>::solve +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,>::load_model +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:1,>::new +FNDA:0,::fmt +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:1,::init_solver +FNDA:0,>::new +FNDA:0,>::stats +FNDA:0,::add_adaptor_info_to_stats +FNDA:0,<_ as conjure_core::solver::SolverAdaptor>::add_adaptor_info_to_stats +FNDA:1,>::stats +FNDA:0,>::new +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,<_ as conjure_core::solver::SolverAdaptor>::add_adaptor_info_to_stats +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FNDA:0,::fmt +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FNDA:0,::len +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,<_ as conjure_core::solver::SolverAdaptor>::init_solver +FNDA:0,::size_hint +FNDA:0,>::load_model +FNDA:0,::init_solver +FNDA:0,<_ as conjure_core::solver::SolverAdaptor>::init_solver +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:1,::add_adaptor_info_to_stats +FNDA:0,::fmt +FNDA:0,>::wall_time_s +FNDA:0,>::stats +FNDA:0,<_ as conjure_core::solver::SolverAdaptor>::get_name +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FNDA:0,::nth +FNDA:0,>::load_model +FNDA:0,::nth +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,>::new +FNDA:1,>::new +FNDA:0,>::solve +FNDA:0,>::new +FNDA:0,>::solve +FNDA:0,>::load_model +FNDA:0,::iter +FNDA:1,>::load_model +FNDA:0,::from_str +FNDA:0,>::wall_time_s +FNDA:0,::iter +FNDA:0,<_ as conjure_core::solver::SolverAdaptor>::add_adaptor_info_to_stats +FNDA:0,::get +FNDA:0,<_ as conjure_core::solver::SolverAdaptor>::get_name +FNDA:0,::next_back +FNDA:0,::len +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,>::stats +FNDA:0,>::stats +FNDA:0,>::save_stats_to_context +FNDA:0,<_ as conjure_core::solver::SolverAdaptor>::init_solver +FNDA:0,::fmt +FNDA:0,::from_str +FNDA:0,::clone +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,>::get_family +FNDA:0,::get +FNDA:1,>::save_stats_to_context +FNDA:0,>::get_family +FNDA:0,>::try_from +FNDA:0,::next_back +FNDA:0,::from_str +FNDA:0,::next +FNDA:0,::next +FNDA:0,>::solve_mut +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::clone +FNDA:0,::len +FNDA:1,::add_adaptor_info_to_stats +FNDA:0,::fmt +FNDA:0,::nth +FNDA:0,>::save_stats_to_context +FNDA:0,>::save_stats_to_context +FNDA:1,::init_solver +FNDA:0,::fmt +FNDA:0,>::solve_mut +FNDA:1,rust_out::main +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,::size_hint +FNDA:0,::fmt +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,<_ as conjure_core::solver::SolverAdaptor>::get_name +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_solver_mod_rs_24_0 +FNDA:0,::next +FNDA:0,::fmt +FNDA:0,>::wall_time_s +FNDA:0,>::solve +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,>::try_from +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:1,>::solve +FNDA:1,>::solve +FNDA:0,::next_back +FNDA:0,::iter +FNDA:0,>::try_from +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,>::save_stats_to_context +FNDA:0,>::solve_mut +FNF:115 +FNH:15 +BRF:0 +BRH:0 +DA:25,1 +DA:26,1 +DA:27,1 +DA:28,1 +DA:29,1 +DA:30,1 +DA:31,1 +DA:32,1 +DA:33,1 +DA:34,1 +DA:35,1 +DA:36,1 +DA:37,1 +DA:38,1 +DA:39,1 +DA:40,1 +DA:41,1 +DA:42,1 +DA:43,1 +DA:44,1 +DA:45,1 +DA:46,1 +DA:47,1 +DA:48,1 +DA:49,1 +DA:50,1 +DA:51,1 +DA:52,1 +DA:53,1 +DA:54,1 +DA:55,1 +DA:56,1 +DA:57,1 +DA:58,1 +DA:59,2 +DA:60,2 +DA:61,2 +DA:62,2 +DA:63,2 +DA:64,1 +DA:65,1 +DA:66,1 +DA:67,1 +DA:119,0 +DA:120,0 +DA:121,0 +DA:128,0 +DA:216,56 +DA:222,0 +DA:223,0 +DA:224,0 +DA:227,56 +DA:228,56 +DA:229,56 +DA:230,56 +DA:231,56 +DA:232,56 +DA:233,56 +DA:257,56 +DA:258,56 +DA:259,56 +DA:260,56 +DA:261,56 +DA:262,56 +DA:263,56 +DA:264,56 +DA:265,56 +DA:266,56 +DA:268,0 +DA:269,0 +DA:270,0 +DA:274,56 +DA:275,56 +DA:276,56 +DA:277,56 +DA:278,56 +DA:279,56 +DA:280,56 +DA:281,56 +DA:285,56 +DA:286,56 +DA:287,56 +DA:288,56 +DA:289,56 +DA:290,56 +DA:291,56 +DA:292,56 +DA:293,56 +DA:294,56 +DA:295,56 +DA:296,56 +DA:297,56 +DA:298,56 +DA:299,56 +DA:300,56 +DA:301,56 +DA:302,56 +DA:303,56 +DA:304,56 +DA:305,56 +DA:306,56 +DA:307,56 +DA:308,56 +DA:309,56 +DA:310,56 +DA:311,56 +DA:312,56 +DA:314,0 +DA:316,56 +DA:318,0 +DA:319,0 +DA:320,0 +DA:321,0 +DA:322,0 +DA:323,0 +DA:324,0 +DA:325,0 +DA:326,0 +DA:327,0 +DA:328,0 +DA:329,0 +DA:330,0 +DA:331,0 +DA:332,0 +DA:333,0 +DA:334,0 +DA:335,0 +DA:336,0 +DA:337,0 +DA:338,0 +DA:339,0 +DA:340,0 +DA:341,0 +DA:342,0 +DA:343,0 +DA:344,0 +DA:345,0 +DA:347,0 +DA:349,0 +DA:353,45 +DA:354,45 +DA:355,45 +DA:358,45 +DA:359,45 +DA:360,45 +DA:361,45 +DA:362,45 +DA:363,45 +DA:364,45 +DA:365,45 +DA:366,45 +DA:367,45 +DA:368,45 +DA:370,0 +DA:371,0 +DA:372,0 +DA:377,0 +LF:157 +LH:112 +end_of_record +SF:crates/conjure_core/src/solver/adaptors/sat_common.rs +FN:154,::clause_to_expression +FN:74,::get_variables +FN:186,::get_reference_index +FN:102,::add_variable +FN:37,::from_conjure +FN:186,::get_reference_index +FN:110,::has_variable:: +FN:205,::handle_not +FN:234,::handle_flat_expression +FN:37,::from_conjure +FN:205,::handle_not +FN:85,::get_index +FN:186,::get_reference_index +FN:284,::default +FN:117,::add_clause +FN:90,::get_name +FN:315,::has_variable +FN:141,::as_expression +FN:117,::add_clause +FN:74,::get_variables +FN:321,<&conjure_core::ast::symbol_table::Name as conjure_core::solver::adaptors::sat_common::HasVariable>::has_variable +FN:249,::handle_and +FN:102,::add_variable +FN:90,::get_name +FN:284,::default +FN:321,<&conjure_core::ast::symbol_table::Name as conjure_core::solver::adaptors::sat_common::HasVariable>::has_variable +FN:102,::add_variable +FN:85,::get_index +FN:110,::has_variable::<_> +FN:321,<&conjure_core::ast::symbol_table::Name as conjure_core::solver::adaptors::sat_common::HasVariable>::has_variable +FN:198,::handle_reference +FN:272,::handle_expression +FN:29,::new +FN:249,::handle_and +FN:154,::clause_to_expression +FN:90,::get_name +FN:315,::has_variable +FN:37,::from_conjure +FN:284,::default +FN:289,::fmt +FN:74,::get_variables +FN:249,::handle_and +FN:130,::add_expression +FN:234,::handle_flat_expression +FN:29,::new +FN:141,::as_expression +FN:272,::handle_expression +FN:29,::new +FN:85,::get_index +FN:289,::fmt +FN:218,::handle_or +FN:218,::handle_or +FN:315,::has_variable +FN:205,::handle_not +FN:130,::add_expression +FN:289,::fmt +FN:154,::clause_to_expression +FN:198,::handle_reference +FN:218,::handle_or +FN:272,::handle_expression +FN:234,::handle_flat_expression +FN:130,::add_expression +FN:198,::handle_reference +FN:110,::has_variable:: +FN:141,::as_expression +FN:117,::add_clause +FNDA:0,::clause_to_expression +FNDA:0,::get_variables +FNDA:0,::get_reference_index +FNDA:0,::add_variable +FNDA:0,::from_conjure +FNDA:0,::get_reference_index +FNDA:0,::has_variable:: +FNDA:0,::handle_not +FNDA:0,::handle_flat_expression +FNDA:0,::from_conjure +FNDA:0,::handle_not +FNDA:0,::get_index +FNDA:0,::get_reference_index +FNDA:0,::default +FNDA:0,::add_clause +FNDA:0,::get_name +FNDA:0,::has_variable +FNDA:0,::as_expression +FNDA:0,::add_clause +FNDA:0,::get_variables +FNDA:0,<&conjure_core::ast::symbol_table::Name as conjure_core::solver::adaptors::sat_common::HasVariable>::has_variable +FNDA:0,::handle_and +FNDA:0,::add_variable +FNDA:0,::get_name +FNDA:0,::default +FNDA:0,<&conjure_core::ast::symbol_table::Name as conjure_core::solver::adaptors::sat_common::HasVariable>::has_variable +FNDA:0,::add_variable +FNDA:0,::get_index +FNDA:0,::has_variable::<_> +FNDA:0,<&conjure_core::ast::symbol_table::Name as conjure_core::solver::adaptors::sat_common::HasVariable>::has_variable +FNDA:0,::handle_reference +FNDA:0,::handle_expression +FNDA:0,::new +FNDA:0,::handle_and +FNDA:0,::clause_to_expression +FNDA:0,::get_name +FNDA:0,::has_variable +FNDA:0,::from_conjure +FNDA:0,::default +FNDA:0,::fmt +FNDA:0,::get_variables +FNDA:0,::handle_and +FNDA:0,::add_expression +FNDA:0,::handle_flat_expression +FNDA:0,::new +FNDA:0,::as_expression +FNDA:0,::handle_expression +FNDA:0,::new +FNDA:0,::get_index +FNDA:0,::fmt +FNDA:0,::handle_or +FNDA:0,::handle_or +FNDA:0,::has_variable +FNDA:0,::handle_not +FNDA:0,::add_expression +FNDA:0,::fmt +FNDA:0,::clause_to_expression +FNDA:0,::handle_reference +FNDA:0,::handle_or +FNDA:0,::handle_expression +FNDA:0,::handle_flat_expression +FNDA:0,::add_expression +FNDA:0,::handle_reference +FNDA:0,::has_variable:: +FNDA:0,::as_expression +FNDA:0,::add_clause +FNF:66 +FNH:0 +BRF:0 +BRH:0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:34,0 +DA:35,0 +DA:37,0 +DA:38,0 +DA:40,0 +DA:42,0 +DA:44,0 +DA:46,0 +DA:47,0 +DA:48,0 +DA:49,0 +DA:50,0 +DA:51,0 +DA:52,0 +DA:53,0 +DA:54,0 +DA:55,0 +DA:56,0 +DA:59,0 +DA:60,0 +DA:61,0 +DA:62,0 +DA:63,0 +DA:64,0 +DA:69,0 +DA:70,0 +DA:74,0 +DA:75,0 +DA:77,0 +DA:78,0 +DA:79,0 +DA:81,0 +DA:82,0 +DA:85,0 +DA:86,0 +DA:87,0 +DA:90,0 +DA:91,0 +DA:92,0 +DA:93,0 +DA:94,0 +DA:95,0 +DA:98,0 +DA:99,0 +DA:102,0 +DA:103,0 +DA:104,0 +DA:105,0 +DA:110,0 +DA:111,0 +DA:112,0 +DA:117,0 +DA:118,0 +DA:119,0 +DA:120,0 +DA:121,0 +DA:123,0 +DA:124,0 +DA:125,0 +DA:130,0 +DA:131,0 +DA:132,0 +DA:134,0 +DA:135,0 +DA:141,0 +DA:142,0 +DA:144,0 +DA:145,0 +DA:148,0 +DA:149,0 +DA:154,0 +DA:155,0 +DA:157,0 +DA:158,0 +DA:159,0 +DA:160,0 +DA:161,0 +DA:162,0 +DA:163,0 +DA:164,0 +DA:165,0 +DA:166,0 +DA:167,0 +DA:168,0 +DA:169,0 +DA:170,0 +DA:171,0 +DA:172,0 +DA:178,0 +DA:179,0 +DA:186,0 +DA:187,0 +DA:188,0 +DA:189,0 +DA:191,0 +DA:198,0 +DA:199,0 +DA:200,0 +DA:205,0 +DA:206,0 +DA:208,0 +DA:209,0 +DA:211,0 +DA:213,0 +DA:218,0 +DA:219,0 +DA:221,0 +DA:222,0 +DA:223,0 +DA:224,0 +DA:225,0 +DA:228,0 +DA:229,0 +DA:234,0 +DA:235,0 +DA:236,0 +DA:237,0 +DA:238,0 +DA:239,0 +DA:240,0 +DA:241,0 +DA:242,0 +DA:244,0 +DA:249,0 +DA:250,0 +DA:251,0 +DA:252,0 +DA:253,0 +DA:255,0 +DA:256,0 +DA:257,0 +DA:258,0 +DA:261,0 +DA:266,0 +DA:267,0 +DA:272,0 +DA:273,0 +DA:274,0 +DA:275,0 +DA:276,0 +DA:277,0 +DA:278,0 +DA:280,0 +DA:284,0 +DA:285,0 +DA:286,0 +DA:289,0 +DA:315,0 +DA:316,0 +DA:317,0 +DA:321,0 +DA:322,0 +DA:323,0 +LF:158 +LH:0 +end_of_record +SF:crates/conjure_core/src/model.rs +FN:96,::gensym +FN:51,::get_domain::{closure#0} +FN:89,::add_constraints +FN:81,::add_constraint +FN:44,::update_domain +FN:67,::set_constraints +FN:77,::set_context +FN:59,::get_constraints_vec +FN:14,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::<_> +FN:27,::new +FN:14,<<::deserialize::__Visitor as serde::de::Visitor>::visit_map::__DeserializeWith as serde::de::Deserialize>::deserialize::<_> +FN:81,::add_constraint +FN:14,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:40,::new_empty +FN:14,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:14,::eq +FN:40,::new_empty +FN:14,<::serialize::__SerializeWith as serde::ser::Serialize>::serialize::<_> +FN:27,::new +FN:14,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::> +FN:59,::get_constraints_vec +FN:14,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:14,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_>::{closure#0} +FN:50,::get_domain +FN:77,::set_context +FN:44,::update_domain +FN:14,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:14,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::<_> +FN:55,::add_variable +FN:59,::get_constraints_vec +FN:14,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:14,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:14,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FN:14,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::> +FN:96,::gensym +FN:14,<<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::__DeserializeWith as serde::de::Deserialize>::deserialize::<_> +FN:14,<<::deserialize::__Visitor as serde::de::Visitor>::visit_map::__DeserializeWith as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FN:96,::gensym +FN:14,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::<_> +FN:89,::add_constraints +FN:14,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:14,<::deserialize::__Field as serde::de::Deserialize>::deserialize::> +FN:14,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:55,::add_variable +FN:51,::get_domain::{closure#0} +FN:14,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:89,::add_constraints +FN:14,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_>::{closure#0} +FN:14,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::>::{closure#0} +FN:14,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::> +FN:14,<::serialize::__SerializeWith as serde::ser::Serialize>::serialize::<_> +FN:67,::set_constraints +FN:55,::add_variable +FN:14,<::serialize::__SerializeWith as serde::ser::Serialize>::serialize::<_> +FN:14,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:14,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:77,::set_context +FN:14,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:14,::eq +FN:27,::new +FN:14,<<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::__DeserializeWith as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FN:44,::update_domain +FN:40,::new_empty +FN:14,<::serialize::__SerializeWith as serde::ser::Serialize>::serialize:: +FN:51,::get_domain::{closure#0} +FN:14,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:14,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:14,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:14,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::> +FN:14,<::deserialize::__Field as serde::de::Deserialize>::deserialize::> +FN:14,<<::deserialize::__Visitor as serde::de::Visitor>::visit_map::__DeserializeWith as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FN:14,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::>::{closure#0} +FN:14,<<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::__DeserializeWith as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FN:14,<<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::__DeserializeWith as serde::de::Deserialize>::deserialize::<_> +FN:14,<<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::__DeserializeWith as serde::de::Deserialize>::deserialize::<_> +FN:14,<::serialize::__SerializeWith as serde::ser::Serialize>::serialize:: +FN:81,::add_constraint +FN:14,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:14,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:14,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FN:50,::get_domain +FN:14,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:14,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:14,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_>::{closure#0} +FN:67,::set_constraints +FN:14,<<::deserialize::__Visitor as serde::de::Visitor>::visit_map::__DeserializeWith as serde::de::Deserialize>::deserialize::<_> +FN:14,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:14,<<::deserialize::__Visitor as serde::de::Visitor>::visit_map::__DeserializeWith as serde::de::Deserialize>::deserialize::<_> +FN:50,::get_domain +FN:14,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_> +FN:14,::eq +FNDA:0,::gensym +FNDA:0,::get_domain::{closure#0} +FNDA:0,::add_constraints +FNDA:0,::add_constraint +FNDA:0,::update_domain +FNDA:0,::set_constraints +FNDA:0,::set_context +FNDA:0,::get_constraints_vec +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::<_> +FNDA:1,::new +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_map::__DeserializeWith as serde::de::Deserialize>::deserialize::<_> +FNDA:0,::add_constraint +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,::new_empty +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,::eq +FNDA:0,::new_empty +FNDA:0,<::serialize::__SerializeWith as serde::ser::Serialize>::serialize::<_> +FNDA:0,::new +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::> +FNDA:1,::get_constraints_vec +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_>::{closure#0} +FNDA:0,::get_domain +FNDA:0,::set_context +FNDA:1,::update_domain +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::<_> +FNDA:0,::add_variable +FNDA:0,::get_constraints_vec +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:1,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,::gensym +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::__DeserializeWith as serde::de::Deserialize>::deserialize::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_map::__DeserializeWith as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FNDA:1,::gensym +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::<_> +FNDA:1,::add_constraints +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:1,<::deserialize::__Field as serde::de::Deserialize>::deserialize::> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:1,::add_variable +FNDA:0,::get_domain::{closure#0} +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::add_constraints +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_>::{closure#0} +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::>::{closure#0} +FNDA:1,<::deserialize::__Visitor as serde::de::Visitor>::visit_map::> +FNDA:0,<::serialize::__SerializeWith as serde::ser::Serialize>::serialize::<_> +FNDA:1,::set_constraints +FNDA:0,::add_variable +FNDA:0,<::serialize::__SerializeWith as serde::ser::Serialize>::serialize::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,::set_context +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:1,::eq +FNDA:0,::new +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::__DeserializeWith as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FNDA:0,::update_domain +FNDA:1,::new_empty +FNDA:1,<::serialize::__SerializeWith as serde::ser::Serialize>::serialize:: +FNDA:0,::get_domain::{closure#0} +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::> +FNDA:1,<<::deserialize::__Visitor as serde::de::Visitor>::visit_map::__DeserializeWith as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::>::{closure#0} +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::__DeserializeWith as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::__DeserializeWith as serde::de::Deserialize>::deserialize::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::__DeserializeWith as serde::de::Deserialize>::deserialize::<_> +FNDA:0,<::serialize::__SerializeWith as serde::ser::Serialize>::serialize:: +FNDA:0,::add_constraint +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FNDA:0,::get_domain +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_>::{closure#0} +FNDA:0,::set_constraints +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_map::__DeserializeWith as serde::de::Deserialize>::deserialize::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,<<::deserialize::__Visitor as serde::de::Visitor>::visit_map::__DeserializeWith as serde::de::Deserialize>::deserialize::<_> +FNDA:0,::get_domain +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::eq +FNF:91 +FNH:14 +BRF:0 +BRH:0 +DA:14,630 +DA:27,6900 +DA:28,6900 +DA:29,6900 +DA:30,6900 +DA:31,6900 +DA:32,6900 +DA:33,6900 +DA:34,6900 +DA:35,6900 +DA:36,6900 +DA:37,6900 +DA:38,6900 +DA:40,6840 +DA:41,6840 +DA:42,6840 +DA:44,15 +DA:45,15 +DA:46,15 +DA:47,15 +DA:48,15 +DA:50,0 +DA:51,0 +DA:52,0 +DA:55,375 +DA:56,375 +DA:57,375 +DA:59,360 +DA:60,360 +DA:61,120 +DA:62,180 +DA:63,60 +DA:65,360 +DA:67,180 +DA:68,180 +DA:69,0 +DA:70,180 +DA:71,150 +DA:72,150 +DA:73,30 +DA:74,30 +DA:75,180 +DA:77,0 +DA:78,0 +DA:79,0 +DA:81,0 +DA:82,0 +DA:83,0 +DA:84,0 +DA:85,0 +DA:86,0 +DA:87,0 +DA:89,180 +DA:90,180 +DA:91,180 +DA:92,180 +DA:93,180 +DA:96,75 +DA:97,75 +DA:98,75 +DA:99,75 +DA:100,75 +LF:62 +LH:48 +end_of_record +SF:crates/uniplate/src/biplate.rs +FN:70,<_ as uniplate::biplate::Uniplate>::universe +FN:64,<_ as uniplate::biplate::Uniplate>::descend +FN:90,<_ as uniplate::biplate::Uniplate>::with_children +FN:138,<_ as uniplate::biplate::Uniplate>::cata::<_> +FN:48,>::children_bi +FN:70,::universe +FN:28,<_ as uniplate::biplate::Biplate<_>>::descend_bi +FN:43,>::universe_bi::{closure#0} +FN:40,>::universe_bi +FN:106,<_ as uniplate::biplate::Uniplate>::transform +FN:54,<_ as uniplate::biplate::Biplate<_>>::transform_bi::{closure#0} +FN:43,<_ as uniplate::biplate::Biplate<_>>::universe_bi::{closure#0} +FN:79,::children +FN:52,<_ as uniplate::biplate::Biplate<_>>::transform_bi +FN:115,<_ as uniplate::biplate::Uniplate>::rewrite +FN:79,<_ as uniplate::biplate::Uniplate>::children +FN:48,<_ as uniplate::biplate::Biplate<_>>::children_bi +FN:119,<_ as uniplate::biplate::Uniplate>::rewrite::{closure#0} +FN:142,<_ as uniplate::biplate::Uniplate>::cata::<_>::{closure#0} +FN:110,<_ as uniplate::biplate::Uniplate>::transform::{closure#0} +FN:40,<_ as uniplate::biplate::Biplate<_>>::universe_bi +FNDA:0,<_ as uniplate::biplate::Uniplate>::universe +FNDA:0,<_ as uniplate::biplate::Uniplate>::descend +FNDA:0,<_ as uniplate::biplate::Uniplate>::with_children +FNDA:0,<_ as uniplate::biplate::Uniplate>::cata::<_> +FNDA:1,>::children_bi +FNDA:1,::universe +FNDA:0,<_ as uniplate::biplate::Biplate<_>>::descend_bi +FNDA:1,>::universe_bi::{closure#0} +FNDA:1,>::universe_bi +FNDA:0,<_ as uniplate::biplate::Uniplate>::transform +FNDA:0,<_ as uniplate::biplate::Biplate<_>>::transform_bi::{closure#0} +FNDA:0,<_ as uniplate::biplate::Biplate<_>>::universe_bi::{closure#0} +FNDA:1,::children +FNDA:0,<_ as uniplate::biplate::Biplate<_>>::transform_bi +FNDA:0,<_ as uniplate::biplate::Uniplate>::rewrite +FNDA:0,<_ as uniplate::biplate::Uniplate>::children +FNDA:0,<_ as uniplate::biplate::Biplate<_>>::children_bi +FNDA:0,<_ as uniplate::biplate::Uniplate>::rewrite::{closure#0} +FNDA:0,<_ as uniplate::biplate::Uniplate>::cata::<_>::{closure#0} +FNDA:0,<_ as uniplate::biplate::Uniplate>::transform::{closure#0} +FNDA:0,<_ as uniplate::biplate::Biplate<_>>::universe_bi +FNF:21 +FNH:5 +BRF:0 +BRH:0 +DA:28,0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:40,1 +DA:41,1 +DA:42,1 +DA:43,4 +DA:44,1 +DA:45,1 +DA:48,2 +DA:49,2 +DA:50,2 +DA:52,0 +DA:53,0 +DA:54,0 +DA:55,0 +DA:64,0 +DA:65,0 +DA:66,0 +DA:67,0 +DA:70,8 +DA:71,8 +DA:72,8 +DA:73,4 +DA:74,4 +DA:75,8 +DA:76,8 +DA:79,8 +DA:80,8 +DA:81,8 +DA:82,8 +DA:90,0 +DA:91,0 +DA:92,0 +DA:93,0 +DA:94,0 +DA:95,0 +DA:96,0 +DA:97,0 +DA:98,0 +DA:99,0 +DA:101,0 +DA:102,0 +DA:103,0 +DA:106,0 +DA:107,0 +DA:108,0 +DA:109,0 +DA:110,0 +DA:111,0 +DA:112,0 +DA:115,0 +DA:116,0 +DA:117,0 +DA:118,0 +DA:119,0 +DA:120,0 +DA:121,0 +DA:122,0 +DA:123,0 +DA:125,0 +DA:138,0 +DA:139,0 +DA:140,0 +DA:141,0 +DA:142,0 +DA:143,0 +DA:144,0 +LF:69 +LH:20 +end_of_record +SF:crates/conjure_core/src/rules/cnf.rs +FN:21,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_AND::__typecheck::{closure#0}::{closure#0} +FN:45,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_OR::__typecheck::{closure#0}::{closure#0} +FN:46,conjure_core::rules::cnf::distribute_not_over_or +FN:12,conjure_core::rules::cnf::CONJURE_GEN_RULE_SET_CNF::__typecheck::{closure#0} +FN:12,conjure_core::rules::cnf::CONJURE_GEN_RULE_SET_CNF::__typecheck +FN:21,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_AND::__typecheck +FN:42,rust_out::main::_doctest_main_crates_conjure_core_src_rules_cnf_rs_42_0 +FN:45,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_OR::__typecheck::{closure#0}::{closure#0} +FN:42,rust_out::main +FN:18,rust_out::main::_doctest_main_crates_conjure_core_src_rules_cnf_rs_18_0 +FN:21,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_AND::__typecheck::{closure#0}::{closure#0} +FN:21,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_AND::__typecheck::{closure#0}::{closure#0} +FN:21,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_AND::__typecheck +FN:45,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_OR::__typecheck::{closure#0} +FN:45,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_OR::__typecheck::{closure#0}::{closure#0} +FN:45,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_OR::__typecheck::{closure#0} +FN:12,conjure_core::rules::cnf::CONJURE_GEN_RULE_SET_CNF::__typecheck::{closure#0} +FN:21,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_AND::__typecheck::{closure#0} +FN:12,conjure_core::rules::cnf::CONJURE_GEN_RULE_SET_CNF::__typecheck::{closure#0}::{closure#0} +FN:45,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_OR::__typecheck +FN:45,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_OR::__typecheck::{closure#0} +FN:46,conjure_core::rules::cnf::distribute_not_over_or +FN:21,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_AND::__typecheck +FN:21,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_AND::__typecheck::{closure#0} +FN:46,conjure_core::rules::cnf::distribute_not_over_or +FN:45,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_OR::__typecheck +FN:21,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_AND::__typecheck::{closure#0} +FN:12,conjure_core::rules::cnf::CONJURE_GEN_RULE_SET_CNF::__typecheck +FN:22,conjure_core::rules::cnf::distribute_not_over_and +FN:12,conjure_core::rules::cnf::CONJURE_GEN_RULE_SET_CNF::__typecheck::{closure#0}::{closure#0} +FN:12,conjure_core::rules::cnf::CONJURE_GEN_RULE_SET_CNF::__typecheck::{closure#0} +FN:45,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_OR::__typecheck +FN:12,conjure_core::rules::cnf::CONJURE_GEN_RULE_SET_CNF::__typecheck::{closure#0}::{closure#0} +FN:22,conjure_core::rules::cnf::distribute_not_over_and +FN:12,conjure_core::rules::cnf::CONJURE_GEN_RULE_SET_CNF::__typecheck +FN:22,conjure_core::rules::cnf::distribute_not_over_and +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_AND::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_OR::__typecheck::{closure#0}::{closure#0} +FNDA:1,conjure_core::rules::cnf::distribute_not_over_or +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_SET_CNF::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_SET_CNF::__typecheck +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_AND::__typecheck +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_cnf_rs_42_0 +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_OR::__typecheck::{closure#0}::{closure#0} +FNDA:1,rust_out::main +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_cnf_rs_18_0 +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_AND::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_AND::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_AND::__typecheck +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_OR::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_OR::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_OR::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_SET_CNF::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_AND::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_SET_CNF::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_OR::__typecheck +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_OR::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::cnf::distribute_not_over_or +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_AND::__typecheck +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_AND::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::cnf::distribute_not_over_or +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_OR::__typecheck +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_AND::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_SET_CNF::__typecheck +FNDA:0,conjure_core::rules::cnf::distribute_not_over_and +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_SET_CNF::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_SET_CNF::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_DISTRIBUTE_NOT_OVER_OR::__typecheck +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_SET_CNF::__typecheck::{closure#0}::{closure#0} +FNDA:1,conjure_core::rules::cnf::distribute_not_over_and +FNDA:0,conjure_core::rules::cnf::CONJURE_GEN_RULE_SET_CNF::__typecheck +FNDA:0,conjure_core::rules::cnf::distribute_not_over_and +FNF:36 +FNH:5 +BRF:0 +BRH:0 +DA:12,0 +DA:18,1 +DA:19,1 +DA:20,1 +DA:21,0 +DA:22,255 +DA:23,255 +DA:24,30 +DA:25,15 +DA:26,15 +DA:27,45 +DA:28,30 +DA:29,30 +DA:30,15 +DA:32,15 +DA:34,225 +DA:36,255 +DA:42,1 +DA:43,1 +DA:44,1 +DA:45,0 +DA:46,255 +DA:47,255 +DA:48,30 +DA:49,15 +DA:50,15 +DA:51,45 +DA:52,30 +DA:53,30 +DA:54,15 +DA:56,15 +DA:58,225 +DA:60,255 +LF:33 +LH:30 +end_of_record +SF:crates/conjure_core/src/ast/constants.rs +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:5,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:5,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:33,::fmt +FN:24,>::try_from +FN:24,>::try_from +FN:14,>::try_from +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:33,::fmt +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:5,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FN:14,>::try_from +FN:5,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:5,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:33,::fmt +FN:24,>::try_from +FN:14,>::try_from +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:5,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:5,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:1,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,::fmt +FNDA:1,>::try_from +FNDA:0,>::try_from +FNDA:0,>::try_from +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,::fmt +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FNDA:0,>::try_from +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:1,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:1,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:0,::fmt +FNDA:0,>::try_from +FNDA:1,>::try_from +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FNF:38 +FNH:5 +BRF:0 +BRH:0 +DA:5,690 +DA:14,1110 +DA:15,1110 +DA:16,1065 +DA:17,45 +DA:19,1110 +DA:24,120 +DA:25,120 +DA:26,105 +DA:27,15 +DA:29,120 +DA:33,0 +DA:34,0 +DA:35,0 +DA:36,0 +DA:38,0 +LF:16 +LH:11 +end_of_record +SF:solvers/minion/src/scoped_ptr.rs +FN:17,>::new +FN:24, as core::ops::drop::Drop>::drop +FN:17,>::new +FN:24, as core::ops::drop::Drop>::drop +FN:24, as core::ops::drop::Drop>::drop +FN:24, as core::ops::drop::Drop>::drop +FN:17,>::new +FN:17,>::new +FN:24, as core::ops::drop::Drop>::drop +FN:24, as core::ops::drop::Drop>::drop +FN:17,>::new +FN:24, as core::ops::drop::Drop>::drop +FN:17,>::new +FN:17,>::new +FNDA:1,>::new +FNDA:0, as core::ops::drop::Drop>::drop +FNDA:1,>::new +FNDA:0, as core::ops::drop::Drop>::drop +FNDA:1, as core::ops::drop::Drop>::drop +FNDA:1, as core::ops::drop::Drop>::drop +FNDA:0,>::new +FNDA:0,>::new +FNDA:0, as core::ops::drop::Drop>::drop +FNDA:0, as core::ops::drop::Drop>::drop +FNDA:0,>::new +FNDA:1, as core::ops::drop::Drop>::drop +FNDA:1,>::new +FNDA:0,>::new +FNF:14 +FNH:6 +BRF:0 +BRH:0 +DA:17,5529 +DA:18,5529 +DA:19,5529 +DA:24,5529 +DA:25,5529 +DA:26,5529 +LF:6 +LH:6 +end_of_record +SF:solvers/minion/src/ffi.rs +FN:16,hello_from_rust +FN:26,minion_rs::ffi::tests::xyz_raw +FNDA:1,hello_from_rust +FNDA:1,minion_rs::ffi::tests::xyz_raw +FNF:2 +FNH:2 +BRF:0 +BRH:0 +DA:16,1 +DA:17,1 +DA:18,1 +DA:19,1 +DA:20,1 +DA:21,1 +DA:22,1 +DA:23,1 +DA:26,1 +DA:27,1 +DA:28,1 +DA:29,1 +DA:30,1 +DA:31,1 +DA:32,1 +DA:33,1 +DA:34,1 +DA:35,1 +DA:36,1 +DA:37,1 +DA:38,1 +DA:39,1 +DA:40,1 +DA:41,1 +DA:42,1 +DA:43,1 +DA:44,1 +DA:45,1 +DA:46,1 +DA:47,1 +DA:48,1 +DA:49,1 +DA:50,1 +DA:51,1 +DA:52,1 +DA:53,1 +DA:54,1 +DA:55,1 +DA:56,1 +DA:57,1 +DA:58,1 +DA:59,1 +DA:60,1 +DA:61,1 +DA:62,1 +DA:63,1 +DA:64,1 +DA:65,1 +DA:66,1 +DA:67,1 +DA:68,1 +DA:69,1 +DA:70,1 +DA:71,1 +DA:72,1 +DA:73,1 +DA:74,1 +DA:75,1 +DA:76,1 +DA:77,1 +DA:78,1 +DA:79,1 +DA:80,1 +DA:81,1 +DA:82,1 +DA:83,1 +DA:84,1 +DA:85,1 +DA:86,1 +DA:87,1 +DA:88,1 +DA:89,1 +DA:90,1 +DA:91,1 +DA:92,1 +DA:93,1 +DA:94,1 +DA:95,1 +DA:96,1 +DA:97,1 +DA:100,1 +DA:101,1 +DA:102,1 +DA:104,1 +LF:84 +LH:84 +end_of_record +SF:crates/conjure_core/src/rules/minion.rs +FN:13,conjure_core::rules::minion::CONJURE_GEN_RULE_SET_MINION::__typecheck::{closure#0} +FN:108,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_EQ_TO_SUMEQ::__typecheck::{closure#0} +FN:138,conjure_core::rules::minion::CONJURE_GEN_RULE_SUMEQ_TO_MINION::__typecheck::{closure#0} +FN:275,conjure_core::rules::minion::CONJURE_GEN_RULE_EQ_TO_LEQ_GEQ::__typecheck +FN:179,conjure_core::rules::minion::CONJURE_GEN_RULE_GT_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FN:264,conjure_core::rules::minion::CONJURE_GEN_RULE_NEQ_TO_ALLDIFF::__typecheck +FN:179,conjure_core::rules::minion::CONJURE_GEN_RULE_GT_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FN:196,rust_out::main::_doctest_main_crates_conjure_core_src_rules_minion_rs_196_0 +FN:139,conjure_core::rules::minion::sumeq_to_minion +FN:179,conjure_core::rules::minion::CONJURE_GEN_RULE_GT_TO_INEQ::__typecheck +FN:87,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_LEQ_TO_SUMLEQ::__typecheck::{closure#0} +FN:87,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_LEQ_TO_SUMLEQ::__typecheck::{closure#0} +FN:87,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_LEQ_TO_SUMLEQ::__typecheck +FN:275,conjure_core::rules::minion::CONJURE_GEN_RULE_EQ_TO_LEQ_GEQ::__typecheck::{closure#0} +FN:176,rust_out::main::_doctest_main_crates_conjure_core_src_rules_minion_rs_176_0 +FN:200,conjure_core::rules::minion::geq_to_ineq +FN:109,conjure_core::rules::minion::sum_eq_to_sumeq +FN:219,conjure_core::rules::minion::CONJURE_GEN_RULE_LEQ_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FN:220,conjure_core::rules::minion::leq_to_ineq +FN:179,conjure_core::rules::minion::CONJURE_GEN_RULE_GT_TO_INEQ::__typecheck::{closure#0} +FN:265,conjure_core::rules::minion::neq_to_alldiff +FN:109,conjure_core::rules::minion::sum_eq_to_sumeq +FN:87,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_LEQ_TO_SUMLEQ::__typecheck::{closure#0} +FN:179,conjure_core::rules::minion::CONJURE_GEN_RULE_GT_TO_INEQ::__typecheck +FN:67,conjure_core::rules::minion::flatten_sum_geq +FN:88,conjure_core::rules::minion::sum_leq_to_sumleq +FN:220,conjure_core::rules::minion::leq_to_ineq +FN:27,conjure_core::rules::minion::sum_to_vector +FN:15,conjure_core::rules::minion::is_nested_sum +FN:13,conjure_core::rules::minion::CONJURE_GEN_RULE_SET_MINION::__typecheck +FN:27,conjure_core::rules::minion::sum_to_vector +FN:160,conjure_core::rules::minion::lt_to_ineq +FN:275,conjure_core::rules::minion::CONJURE_GEN_RULE_EQ_TO_LEQ_GEQ::__typecheck +FN:180,conjure_core::rules::minion::gt_to_ineq +FN:264,conjure_core::rules::minion::CONJURE_GEN_RULE_NEQ_TO_ALLDIFF::__typecheck::{closure#0}::{closure#0} +FN:88,conjure_core::rules::minion::sum_leq_to_sumleq +FN:219,conjure_core::rules::minion::CONJURE_GEN_RULE_LEQ_TO_INEQ::__typecheck::{closure#0} +FN:138,conjure_core::rules::minion::CONJURE_GEN_RULE_SUMEQ_TO_MINION::__typecheck::{closure#0}::{closure#0} +FN:219,conjure_core::rules::minion::CONJURE_GEN_RULE_LEQ_TO_INEQ::__typecheck::{closure#0} +FN:264,conjure_core::rules::minion::CONJURE_GEN_RULE_NEQ_TO_ALLDIFF::__typecheck +FN:87,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_LEQ_TO_SUMLEQ::__typecheck::{closure#0}::{closure#0} +FN:138,conjure_core::rules::minion::CONJURE_GEN_RULE_SUMEQ_TO_MINION::__typecheck +FN:138,conjure_core::rules::minion::CONJURE_GEN_RULE_SUMEQ_TO_MINION::__typecheck::{closure#0}::{closure#0} +FN:108,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_EQ_TO_SUMEQ::__typecheck +FN:13,conjure_core::rules::minion::CONJURE_GEN_RULE_SET_MINION::__typecheck::{closure#0} +FN:15,conjure_core::rules::minion::is_nested_sum +FN:138,conjure_core::rules::minion::CONJURE_GEN_RULE_SUMEQ_TO_MINION::__typecheck::{closure#0} +FN:264,conjure_core::rules::minion::CONJURE_GEN_RULE_NEQ_TO_ALLDIFF::__typecheck::{closure#0} +FN:179,conjure_core::rules::minion::CONJURE_GEN_RULE_GT_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FN:108,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_EQ_TO_SUMEQ::__typecheck::{closure#0} +FN:160,conjure_core::rules::minion::lt_to_ineq +FN:156,rust_out::main::_doctest_main_crates_conjure_core_src_rules_minion_rs_156_0 +FN:276,conjure_core::rules::minion::eq_to_leq_geq +FN:13,conjure_core::rules::minion::CONJURE_GEN_RULE_SET_MINION::__typecheck::{closure#0}::{closure#0} +FN:135,rust_out::main::_doctest_main_crates_conjure_core_src_rules_minion_rs_135_0 +FN:264,conjure_core::rules::minion::CONJURE_GEN_RULE_NEQ_TO_ALLDIFF::__typecheck::{closure#0} +FN:159,conjure_core::rules::minion::CONJURE_GEN_RULE_LT_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FN:219,conjure_core::rules::minion::CONJURE_GEN_RULE_LEQ_TO_INEQ::__typecheck +FN:264,conjure_core::rules::minion::CONJURE_GEN_RULE_NEQ_TO_ALLDIFF::__typecheck::{closure#0}::{closure#0} +FN:108,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_EQ_TO_SUMEQ::__typecheck::{closure#0}::{closure#0} +FN:108,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_EQ_TO_SUMEQ::__typecheck +FN:200,conjure_core::rules::minion::geq_to_ineq +FN:275,conjure_core::rules::minion::CONJURE_GEN_RULE_EQ_TO_LEQ_GEQ::__typecheck::{closure#0} +FN:13,conjure_core::rules::minion::CONJURE_GEN_RULE_SET_MINION::__typecheck::{closure#0}::{closure#0} +FN:138,conjure_core::rules::minion::CONJURE_GEN_RULE_SUMEQ_TO_MINION::__typecheck +FN:66,conjure_core::rules::minion::CONJURE_GEN_RULE_FLATTEN_SUM_GEQ::__typecheck::{closure#0} +FN:66,conjure_core::rules::minion::CONJURE_GEN_RULE_FLATTEN_SUM_GEQ::__typecheck::{closure#0}::{closure#0} +FN:138,conjure_core::rules::minion::CONJURE_GEN_RULE_SUMEQ_TO_MINION::__typecheck::{closure#0} +FN:264,conjure_core::rules::minion::CONJURE_GEN_RULE_NEQ_TO_ALLDIFF::__typecheck::{closure#0}::{closure#0} +FN:180,conjure_core::rules::minion::gt_to_ineq +FN:108,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_EQ_TO_SUMEQ::__typecheck::{closure#0} +FN:138,conjure_core::rules::minion::CONJURE_GEN_RULE_SUMEQ_TO_MINION::__typecheck::{closure#0}::{closure#0} +FN:66,conjure_core::rules::minion::CONJURE_GEN_RULE_FLATTEN_SUM_GEQ::__typecheck::{closure#0}::{closure#0} +FN:199,conjure_core::rules::minion::CONJURE_GEN_RULE_GEQ_TO_INEQ::__typecheck::{closure#0} +FN:159,conjure_core::rules::minion::CONJURE_GEN_RULE_LT_TO_INEQ::__typecheck +FN:108,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_EQ_TO_SUMEQ::__typecheck::{closure#0}::{closure#0} +FN:105,rust_out::main::_doctest_main_crates_conjure_core_src_rules_minion_rs_105_0 +FN:130,rust_out::main::_doctest_main_crates_conjure_core_src_rules_minion_rs_130_0 +FN:264,conjure_core::rules::minion::CONJURE_GEN_RULE_NEQ_TO_ALLDIFF::__typecheck::{closure#0} +FN:219,conjure_core::rules::minion::CONJURE_GEN_RULE_LEQ_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FN:138,conjure_core::rules::minion::CONJURE_GEN_RULE_SUMEQ_TO_MINION::__typecheck +FN:219,conjure_core::rules::minion::CONJURE_GEN_RULE_LEQ_TO_INEQ::__typecheck::{closure#0} +FN:159,conjure_core::rules::minion::CONJURE_GEN_RULE_LT_TO_INEQ::__typecheck::{closure#0} +FN:66,conjure_core::rules::minion::CONJURE_GEN_RULE_FLATTEN_SUM_GEQ::__typecheck::{closure#0} +FN:66,conjure_core::rules::minion::CONJURE_GEN_RULE_FLATTEN_SUM_GEQ::__typecheck::{closure#0}::{closure#0} +FN:27,conjure_core::rules::minion::sum_to_vector +FN:88,conjure_core::rules::minion::sum_leq_to_sumleq +FN:159,conjure_core::rules::minion::CONJURE_GEN_RULE_LT_TO_INEQ::__typecheck +FN:275,conjure_core::rules::minion::CONJURE_GEN_RULE_EQ_TO_LEQ_GEQ::__typecheck::{closure#0}::{closure#0} +FN:265,conjure_core::rules::minion::neq_to_alldiff +FN:159,conjure_core::rules::minion::CONJURE_GEN_RULE_LT_TO_INEQ::__typecheck +FN:265,conjure_core::rules::minion::neq_to_alldiff +FN:179,conjure_core::rules::minion::CONJURE_GEN_RULE_GT_TO_INEQ::__typecheck +FN:108,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_EQ_TO_SUMEQ::__typecheck +FN:13,conjure_core::rules::minion::CONJURE_GEN_RULE_SET_MINION::__typecheck::{closure#0} +FN:179,conjure_core::rules::minion::CONJURE_GEN_RULE_GT_TO_INEQ::__typecheck::{closure#0} +FN:199,conjure_core::rules::minion::CONJURE_GEN_RULE_GEQ_TO_INEQ::__typecheck +FN:67,conjure_core::rules::minion::flatten_sum_geq +FN:219,conjure_core::rules::minion::CONJURE_GEN_RULE_LEQ_TO_INEQ::__typecheck +FN:219,conjure_core::rules::minion::CONJURE_GEN_RULE_LEQ_TO_INEQ::__typecheck +FN:66,conjure_core::rules::minion::CONJURE_GEN_RULE_FLATTEN_SUM_GEQ::__typecheck::{closure#0} +FN:276,conjure_core::rules::minion::eq_to_leq_geq +FN:180,conjure_core::rules::minion::gt_to_ineq +FN:275,conjure_core::rules::minion::CONJURE_GEN_RULE_EQ_TO_LEQ_GEQ::__typecheck +FN:87,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_LEQ_TO_SUMLEQ::__typecheck::{closure#0}::{closure#0} +FN:200,conjure_core::rules::minion::geq_to_ineq +FN:139,conjure_core::rules::minion::sumeq_to_minion +FN:109,conjure_core::rules::minion::sum_eq_to_sumeq +FN:264,conjure_core::rules::minion::CONJURE_GEN_RULE_NEQ_TO_ALLDIFF::__typecheck +FN:159,conjure_core::rules::minion::CONJURE_GEN_RULE_LT_TO_INEQ::__typecheck::{closure#0} +FN:159,conjure_core::rules::minion::CONJURE_GEN_RULE_LT_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FN:219,conjure_core::rules::minion::CONJURE_GEN_RULE_LEQ_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FN:196,rust_out::main +FN:276,conjure_core::rules::minion::eq_to_leq_geq +FN:13,conjure_core::rules::minion::CONJURE_GEN_RULE_SET_MINION::__typecheck +FN:66,conjure_core::rules::minion::CONJURE_GEN_RULE_FLATTEN_SUM_GEQ::__typecheck +FN:199,conjure_core::rules::minion::CONJURE_GEN_RULE_GEQ_TO_INEQ::__typecheck::{closure#0} +FN:199,conjure_core::rules::minion::CONJURE_GEN_RULE_GEQ_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FN:159,conjure_core::rules::minion::CONJURE_GEN_RULE_LT_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FN:199,conjure_core::rules::minion::CONJURE_GEN_RULE_GEQ_TO_INEQ::__typecheck +FN:87,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_LEQ_TO_SUMLEQ::__typecheck::{closure#0}::{closure#0} +FN:159,conjure_core::rules::minion::CONJURE_GEN_RULE_LT_TO_INEQ::__typecheck::{closure#0} +FN:15,conjure_core::rules::minion::is_nested_sum +FN:13,conjure_core::rules::minion::CONJURE_GEN_RULE_SET_MINION::__typecheck::{closure#0}::{closure#0} +FN:199,conjure_core::rules::minion::CONJURE_GEN_RULE_GEQ_TO_INEQ::__typecheck::{closure#0} +FN:87,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_LEQ_TO_SUMLEQ::__typecheck +FN:179,conjure_core::rules::minion::CONJURE_GEN_RULE_GT_TO_INEQ::__typecheck::{closure#0} +FN:199,conjure_core::rules::minion::CONJURE_GEN_RULE_GEQ_TO_INEQ::__typecheck +FN:63,rust_out::main::_doctest_main_crates_conjure_core_src_rules_minion_rs_63_0 +FN:160,conjure_core::rules::minion::lt_to_ineq +FN:67,conjure_core::rules::minion::flatten_sum_geq +FN:108,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_EQ_TO_SUMEQ::__typecheck::{closure#0}::{closure#0} +FN:13,conjure_core::rules::minion::CONJURE_GEN_RULE_SET_MINION::__typecheck +FN:199,conjure_core::rules::minion::CONJURE_GEN_RULE_GEQ_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FN:139,conjure_core::rules::minion::sumeq_to_minion +FN:220,conjure_core::rules::minion::leq_to_ineq +FN:66,conjure_core::rules::minion::CONJURE_GEN_RULE_FLATTEN_SUM_GEQ::__typecheck +FN:275,conjure_core::rules::minion::CONJURE_GEN_RULE_EQ_TO_LEQ_GEQ::__typecheck::{closure#0}::{closure#0} +FN:199,conjure_core::rules::minion::CONJURE_GEN_RULE_GEQ_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FN:216,rust_out::main::_doctest_main_crates_conjure_core_src_rules_minion_rs_216_0 +FN:87,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_LEQ_TO_SUMLEQ::__typecheck +FN:275,conjure_core::rules::minion::CONJURE_GEN_RULE_EQ_TO_LEQ_GEQ::__typecheck::{closure#0}::{closure#0} +FN:84,rust_out::main::_doctest_main_crates_conjure_core_src_rules_minion_rs_84_0 +FN:275,conjure_core::rules::minion::CONJURE_GEN_RULE_EQ_TO_LEQ_GEQ::__typecheck::{closure#0} +FN:66,conjure_core::rules::minion::CONJURE_GEN_RULE_FLATTEN_SUM_GEQ::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SET_MINION::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_EQ_TO_SUMEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUMEQ_TO_MINION::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_EQ_TO_LEQ_GEQ::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_GT_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_NEQ_TO_ALLDIFF::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_GT_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_minion_rs_196_0 +FNDA:0,conjure_core::rules::minion::sumeq_to_minion +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_GT_TO_INEQ::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_LEQ_TO_SUMLEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_LEQ_TO_SUMLEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_LEQ_TO_SUMLEQ::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_EQ_TO_LEQ_GEQ::__typecheck::{closure#0} +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_minion_rs_176_0 +FNDA:0,conjure_core::rules::minion::geq_to_ineq +FNDA:0,conjure_core::rules::minion::sum_eq_to_sumeq +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_LEQ_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::leq_to_ineq +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_GT_TO_INEQ::__typecheck::{closure#0} +FNDA:1,conjure_core::rules::minion::neq_to_alldiff +FNDA:1,conjure_core::rules::minion::sum_eq_to_sumeq +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_LEQ_TO_SUMLEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_GT_TO_INEQ::__typecheck +FNDA:0,conjure_core::rules::minion::flatten_sum_geq +FNDA:1,conjure_core::rules::minion::sum_leq_to_sumleq +FNDA:0,conjure_core::rules::minion::leq_to_ineq +FNDA:1,conjure_core::rules::minion::sum_to_vector +FNDA:1,conjure_core::rules::minion::is_nested_sum +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SET_MINION::__typecheck +FNDA:0,conjure_core::rules::minion::sum_to_vector +FNDA:1,conjure_core::rules::minion::lt_to_ineq +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_EQ_TO_LEQ_GEQ::__typecheck +FNDA:0,conjure_core::rules::minion::gt_to_ineq +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_NEQ_TO_ALLDIFF::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::sum_leq_to_sumleq +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_LEQ_TO_INEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUMEQ_TO_MINION::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_LEQ_TO_INEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_NEQ_TO_ALLDIFF::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_LEQ_TO_SUMLEQ::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUMEQ_TO_MINION::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUMEQ_TO_MINION::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_EQ_TO_SUMEQ::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SET_MINION::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::is_nested_sum +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUMEQ_TO_MINION::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_NEQ_TO_ALLDIFF::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_GT_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_EQ_TO_SUMEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::lt_to_ineq +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_minion_rs_156_0 +FNDA:0,conjure_core::rules::minion::eq_to_leq_geq +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SET_MINION::__typecheck::{closure#0}::{closure#0} +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_minion_rs_135_0 +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_NEQ_TO_ALLDIFF::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_LT_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_LEQ_TO_INEQ::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_NEQ_TO_ALLDIFF::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_EQ_TO_SUMEQ::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_EQ_TO_SUMEQ::__typecheck +FNDA:1,conjure_core::rules::minion::geq_to_ineq +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_EQ_TO_LEQ_GEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SET_MINION::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUMEQ_TO_MINION::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_FLATTEN_SUM_GEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_FLATTEN_SUM_GEQ::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUMEQ_TO_MINION::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_NEQ_TO_ALLDIFF::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::gt_to_ineq +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_EQ_TO_SUMEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUMEQ_TO_MINION::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_FLATTEN_SUM_GEQ::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_GEQ_TO_INEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_LT_TO_INEQ::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_EQ_TO_SUMEQ::__typecheck::{closure#0}::{closure#0} +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_minion_rs_105_0 +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_minion_rs_130_0 +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_NEQ_TO_ALLDIFF::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_LEQ_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUMEQ_TO_MINION::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_LEQ_TO_INEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_LT_TO_INEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_FLATTEN_SUM_GEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_FLATTEN_SUM_GEQ::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::sum_to_vector +FNDA:0,conjure_core::rules::minion::sum_leq_to_sumleq +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_LT_TO_INEQ::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_EQ_TO_LEQ_GEQ::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::neq_to_alldiff +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_LT_TO_INEQ::__typecheck +FNDA:0,conjure_core::rules::minion::neq_to_alldiff +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_GT_TO_INEQ::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_EQ_TO_SUMEQ::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SET_MINION::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_GT_TO_INEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_GEQ_TO_INEQ::__typecheck +FNDA:0,conjure_core::rules::minion::flatten_sum_geq +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_LEQ_TO_INEQ::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_LEQ_TO_INEQ::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_FLATTEN_SUM_GEQ::__typecheck::{closure#0} +FNDA:1,conjure_core::rules::minion::eq_to_leq_geq +FNDA:1,conjure_core::rules::minion::gt_to_ineq +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_EQ_TO_LEQ_GEQ::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_LEQ_TO_SUMLEQ::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::geq_to_ineq +FNDA:1,conjure_core::rules::minion::sumeq_to_minion +FNDA:0,conjure_core::rules::minion::sum_eq_to_sumeq +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_NEQ_TO_ALLDIFF::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_LT_TO_INEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_LT_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_LEQ_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FNDA:1,rust_out::main +FNDA:0,conjure_core::rules::minion::eq_to_leq_geq +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SET_MINION::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_FLATTEN_SUM_GEQ::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_GEQ_TO_INEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_GEQ_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_LT_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_GEQ_TO_INEQ::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_LEQ_TO_SUMLEQ::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_LT_TO_INEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::is_nested_sum +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SET_MINION::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_GEQ_TO_INEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_LEQ_TO_SUMLEQ::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_GT_TO_INEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_GEQ_TO_INEQ::__typecheck +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_minion_rs_63_0 +FNDA:0,conjure_core::rules::minion::lt_to_ineq +FNDA:1,conjure_core::rules::minion::flatten_sum_geq +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_EQ_TO_SUMEQ::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SET_MINION::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_GEQ_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::sumeq_to_minion +FNDA:1,conjure_core::rules::minion::leq_to_ineq +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_FLATTEN_SUM_GEQ::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_EQ_TO_LEQ_GEQ::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_GEQ_TO_INEQ::__typecheck::{closure#0}::{closure#0} +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_minion_rs_216_0 +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_SUM_LEQ_TO_SUMLEQ::__typecheck +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_EQ_TO_LEQ_GEQ::__typecheck::{closure#0}::{closure#0} +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rules_minion_rs_84_0 +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_EQ_TO_LEQ_GEQ::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::minion::CONJURE_GEN_RULE_FLATTEN_SUM_GEQ::__typecheck +FNF:145 +FNH:22 +BRF:0 +BRH:0 +DA:13,0 +DA:15,120 +DA:16,375 +DA:17,285 +DA:18,30 +DA:19,255 +DA:21,90 +DA:22,120 +DA:27,975 +DA:28,975 +DA:29,120 +DA:30,120 +DA:31,30 +DA:33,90 +DA:36,855 +DA:38,975 +DA:63,1 +DA:64,1 +DA:65,1 +DA:66,0 +DA:67,29625 +DA:68,29625 +DA:69,360 +DA:70,360 +DA:71,15 +DA:72,15 +DA:73,15 +DA:74,15 +DA:75,15 +DA:77,29265 +DA:79,29625 +DA:84,1 +DA:85,1 +DA:86,1 +DA:87,0 +DA:88,29625 +DA:89,29625 +DA:90,510 +DA:91,510 +DA:92,15 +DA:93,15 +DA:94,15 +DA:95,15 +DA:96,15 +DA:98,29115 +DA:100,29625 +DA:105,1 +DA:106,1 +DA:107,1 +DA:108,0 +DA:109,29610 +DA:110,29610 +DA:111,45 +DA:112,45 +DA:113,30 +DA:114,30 +DA:115,30 +DA:116,30 +DA:117,30 +DA:119,29565 +DA:121,29610 +DA:130,1 +DA:131,1 +DA:132,1 +DA:135,1 +DA:136,1 +DA:137,1 +DA:138,0 +DA:139,29610 +DA:140,29610 +DA:141,30 +DA:142,30 +DA:143,30 +DA:144,30 +DA:145,30 +DA:146,30 +DA:147,30 +DA:148,29580 +DA:150,29610 +DA:156,1 +DA:157,1 +DA:158,1 +DA:159,0 +DA:160,29625 +DA:161,29625 +DA:162,30 +DA:163,30 +DA:164,30 +DA:165,30 +DA:166,30 +DA:167,30 +DA:168,29595 +DA:170,29625 +DA:176,1 +DA:177,1 +DA:178,1 +DA:179,0 +DA:180,29610 +DA:181,29610 +DA:182,0 +DA:183,0 +DA:184,0 +DA:185,0 +DA:186,0 +DA:187,0 +DA:188,29610 +DA:190,29610 +DA:196,1 +DA:197,1 +DA:198,1 +DA:199,0 +DA:200,29610 +DA:201,29610 +DA:202,345 +DA:203,345 +DA:204,345 +DA:205,345 +DA:206,345 +DA:207,345 +DA:208,29265 +DA:210,29610 +DA:216,1 +DA:217,1 +DA:218,1 +DA:219,0 +DA:220,29610 +DA:221,29610 +DA:222,495 +DA:223,495 +DA:224,495 +DA:225,495 +DA:226,495 +DA:227,495 +DA:228,29115 +DA:230,29610 +DA:264,0 +DA:265,29610 +DA:266,29610 +DA:267,30 +DA:268,30 +DA:269,30 +DA:270,30 +DA:271,29580 +DA:273,29610 +DA:275,0 +DA:276,29610 +DA:277,29610 +DA:278,45 +DA:279,45 +DA:280,30 +DA:281,30 +DA:282,30 +DA:283,30 +DA:284,30 +DA:285,15 +DA:286,0 +DA:287,0 +DA:288,0 +DA:289,0 +DA:290,0 +DA:292,15 +DA:295,29565 +DA:297,29610 +LF:163 +LH:141 +end_of_record +SF:solvers/chuffed/src/lib.rs +FN:16,chuffed_rs::wrappers::create_var +FN:26,chuffed_rs::wrappers::create_vars +FN:60,chuffed_rs::wrappers::var_sym_break_wrapper +FN:66,chuffed_rs::wrappers::int_plus_wrapper +FN:36,chuffed_rs::wrappers::all_different_wrapper +FN:43,chuffed_rs::wrappers::branch_wrapper +FN:66,chuffed_rs::wrappers::int_plus_wrapper +FN:43,chuffed_rs::wrappers::branch_wrapper +FN:36,chuffed_rs::wrappers::all_different_wrapper +FN:16,chuffed_rs::wrappers::create_var +FN:26,chuffed_rs::wrappers::create_vars +FN:60,chuffed_rs::wrappers::var_sym_break_wrapper +FN:53,chuffed_rs::wrappers::output_vars_wrapper +FN:53,chuffed_rs::wrappers::output_vars_wrapper +FNDA:0,chuffed_rs::wrappers::create_var +FNDA:0,chuffed_rs::wrappers::create_vars +FNDA:0,chuffed_rs::wrappers::var_sym_break_wrapper +FNDA:0,chuffed_rs::wrappers::int_plus_wrapper +FNDA:0,chuffed_rs::wrappers::all_different_wrapper +FNDA:0,chuffed_rs::wrappers::branch_wrapper +FNDA:0,chuffed_rs::wrappers::int_plus_wrapper +FNDA:0,chuffed_rs::wrappers::branch_wrapper +FNDA:0,chuffed_rs::wrappers::all_different_wrapper +FNDA:0,chuffed_rs::wrappers::create_var +FNDA:0,chuffed_rs::wrappers::create_vars +FNDA:0,chuffed_rs::wrappers::var_sym_break_wrapper +FNDA:0,chuffed_rs::wrappers::output_vars_wrapper +FNDA:0,chuffed_rs::wrappers::output_vars_wrapper +FNF:14 +FNH:0 +BRF:0 +BRH:0 +DA:16,0 +DA:17,0 +DA:18,0 +DA:19,0 +DA:20,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:36,0 +DA:37,0 +DA:38,0 +DA:39,0 +DA:40,0 +DA:43,0 +DA:44,0 +DA:45,0 +DA:46,0 +DA:47,0 +DA:48,0 +DA:49,0 +DA:50,0 +DA:51,0 +DA:53,0 +DA:54,0 +DA:55,0 +DA:56,0 +DA:57,0 +DA:58,0 +DA:60,0 +DA:61,0 +DA:62,0 +DA:63,0 +DA:64,0 +DA:66,0 +DA:67,0 +DA:68,0 +DA:69,0 +DA:70,0 +LF:46 +LH:0 +end_of_record +SF:crates/conjure_core/src/solver/adaptors/kissat.rs +FN:24,::new +FN:55,::load_model +FN:60,::get_family +FN:47,::solve_mut +FN:33,::default +FN:55,::load_model +FN:24,::new +FN:24,::new +FN:60,::get_family +FN:39,::solve +FN:60,::get_family +FN:55,::load_model +FN:33,::default +FN:47,::solve_mut +FN:39,::solve +FN:47,::solve_mut +FN:33,::default +FN:39,::solve +FNDA:0,::new +FNDA:0,::load_model +FNDA:0,::get_family +FNDA:0,::solve_mut +FNDA:0,::default +FNDA:0,::load_model +FNDA:0,::new +FNDA:0,::new +FNDA:0,::get_family +FNDA:0,::solve +FNDA:0,::get_family +FNDA:0,::load_model +FNDA:0,::default +FNDA:0,::solve_mut +FNDA:0,::solve +FNDA:0,::solve_mut +FNDA:0,::default +FNDA:0,::solve +FNF:18 +FNH:0 +BRF:0 +BRH:0 +DA:24,0 +DA:25,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:29,0 +DA:33,0 +DA:34,0 +DA:35,0 +DA:39,0 +DA:40,0 +DA:41,0 +DA:42,0 +DA:43,0 +DA:44,0 +DA:45,0 +DA:47,0 +DA:48,0 +DA:49,0 +DA:50,0 +DA:51,0 +DA:52,0 +DA:53,0 +DA:55,0 +DA:56,0 +DA:57,0 +DA:58,0 +DA:60,0 +DA:61,0 +DA:62,0 +LF:30 +LH:0 +end_of_record +SF:solvers/kissat/src/lib.rs +FN:3,kissat_rs::test1 +FNDA:1,kissat_rs::test1 +FNF:1 +FNH:1 +BRF:0 +BRH:0 +DA:3,1 +DA:4,1 +DA:5,1 +DA:6,1 +DA:7,1 +DA:8,1 +DA:9,1 +DA:10,1 +DA:11,1 +DA:12,1 +DA:13,1 +DA:14,1 +DA:15,1 +DA:18,1 +DA:19,1 +DA:20,1 +DA:21,1 +DA:22,0 +DA:25,1 +DA:26,1 +DA:27,1 +DA:28,1 +DA:29,1 +DA:30,1 +DA:31,1 +LF:25 +LH:24 +end_of_record +SF:solvers/minion/src/run.rs +FN:630,minion_rs::run::read_var::{closure#1} +FN:296,minion_rs::run::get_constraint_type +FN:751,minion_rs::run::read_constraint_list::{closure#1} +FN:655,minion_rs::run::read_2_vars::{closure#0} +FN:384,minion_rs::run::constraint_add_args +FN:630,minion_rs::run::read_var::{closure#1} +FN:746,minion_rs::run::read_constraint_list::{closure#0} +FN:741,minion_rs::run::read_constraint_list +FN:270,minion_rs::run::convert_model_to_raw::{closure#2} +FN:221,minion_rs::run::convert_model_to_raw::{closure#0} +FN:229,minion_rs::run::convert_model_to_raw::{closure#1} +FN:168,minion_rs::run::run_minion::{closure#0} +FN:684,minion_rs::run::read_constant +FN:270,minion_rs::run::convert_model_to_raw::{closure#2} +FN:162,minion_rs::run::run_minion +FN:704,minion_rs::run::read_constant_list::{closure#0} +FN:627,minion_rs::run::read_var::{closure#0} +FN:731,minion_rs::run::read_constraint::{closure#0} +FN:296,minion_rs::run::get_constraint_type +FN:731,minion_rs::run::read_constraint::{closure#0} +FN:599,minion_rs::run::read_list::{closure#0} +FN:599,minion_rs::run::read_list::{closure#0} +FN:229,minion_rs::run::convert_model_to_raw::{closure#1} +FN:622,minion_rs::run::read_var +FN:741,minion_rs::run::read_constraint_list +FN:751,minion_rs::run::read_constraint_list::{closure#1} +FN:627,minion_rs::run::read_var::{closure#0} +FN:221,minion_rs::run::convert_model_to_raw::{closure#0} +FN:285,minion_rs::run::convert_model_to_raw::{closure#3} +FN:204,minion_rs::run::convert_model_to_raw +FN:594,minion_rs::run::read_list +FN:168,minion_rs::run::run_minion::{closure#0} +FN:627,minion_rs::run::read_var::{closure#0} +FN:270,minion_rs::run::convert_model_to_raw::{closure#2} +FN:741,minion_rs::run::read_constraint_list +FN:630,minion_rs::run::read_var::{closure#1} +FN:594,minion_rs::run::read_list +FN:162,minion_rs::run::run_minion +FN:647,minion_rs::run::read_2_vars +FN:285,minion_rs::run::convert_model_to_raw::{closure#3} +FN:41,rust_out::main::_doctest_main_solvers_minion_src_run_rs_28_0::callback +FN:168,minion_rs::run::run_minion::{closure#0} +FN:700,minion_rs::run::read_constant_list +FN:204,minion_rs::run::convert_model_to_raw +FN:684,minion_rs::run::read_constant +FN:684,minion_rs::run::read_constant +FN:751,minion_rs::run::read_constraint_list::{closure#1} +FN:29,rust_out::main +FN:704,minion_rs::run::read_constant_list::{closure#0} +FN:594,minion_rs::run::read_list +FN:603,minion_rs::run::read_list::{closure#1} +FN:229,minion_rs::run::convert_model_to_raw::{closure#1} +FN:667,minion_rs::run::read_2_vars::{closure#1} +FN:667,minion_rs::run::read_2_vars::{closure#1} +FN:655,minion_rs::run::read_2_vars::{closure#0} +FN:746,minion_rs::run::read_constraint_list::{closure#0} +FN:162,minion_rs::run::run_minion +FN:603,minion_rs::run::read_list::{closure#1} +FN:725,minion_rs::run::read_constraint +FN:647,minion_rs::run::read_2_vars +FN:700,minion_rs::run::read_constant_list +FN:700,minion_rs::run::read_constant_list +FN:603,minion_rs::run::read_list::{closure#1} +FN:29,rust_out::main::_doctest_main_solvers_minion_src_run_rs_28_0 +FN:647,minion_rs::run::read_2_vars +FN:622,minion_rs::run::read_var +FN:384,minion_rs::run::constraint_add_args +FN:731,minion_rs::run::read_constraint::{closure#0} +FN:384,minion_rs::run::constraint_add_args +FN:285,minion_rs::run::convert_model_to_raw::{closure#3} +FN:725,minion_rs::run::read_constraint +FN:622,minion_rs::run::read_var +FN:667,minion_rs::run::read_2_vars::{closure#1} +FN:725,minion_rs::run::read_constraint +FN:746,minion_rs::run::read_constraint_list::{closure#0} +FN:599,minion_rs::run::read_list::{closure#0} +FN:296,minion_rs::run::get_constraint_type +FN:204,minion_rs::run::convert_model_to_raw +FN:119,run_callback +FN:704,minion_rs::run::read_constant_list::{closure#0} +FN:655,minion_rs::run::read_2_vars::{closure#0} +FN:221,minion_rs::run::convert_model_to_raw::{closure#0} +FNDA:0,minion_rs::run::read_var::{closure#1} +FNDA:0,minion_rs::run::get_constraint_type +FNDA:0,minion_rs::run::read_constraint_list::{closure#1} +FNDA:0,minion_rs::run::read_2_vars::{closure#0} +FNDA:1,minion_rs::run::constraint_add_args +FNDA:0,minion_rs::run::read_var::{closure#1} +FNDA:0,minion_rs::run::read_constraint_list::{closure#0} +FNDA:0,minion_rs::run::read_constraint_list +FNDA:0,minion_rs::run::convert_model_to_raw::{closure#2} +FNDA:0,minion_rs::run::convert_model_to_raw::{closure#0} +FNDA:0,minion_rs::run::convert_model_to_raw::{closure#1} +FNDA:1,minion_rs::run::run_minion::{closure#0} +FNDA:0,minion_rs::run::read_constant +FNDA:1,minion_rs::run::convert_model_to_raw::{closure#2} +FNDA:1,minion_rs::run::run_minion +FNDA:0,minion_rs::run::read_constant_list::{closure#0} +FNDA:0,minion_rs::run::read_var::{closure#0} +FNDA:1,minion_rs::run::read_constraint::{closure#0} +FNDA:0,minion_rs::run::get_constraint_type +FNDA:0,minion_rs::run::read_constraint::{closure#0} +FNDA:0,minion_rs::run::read_list::{closure#0} +FNDA:0,minion_rs::run::read_list::{closure#0} +FNDA:0,minion_rs::run::convert_model_to_raw::{closure#1} +FNDA:1,minion_rs::run::read_var +FNDA:0,minion_rs::run::read_constraint_list +FNDA:1,minion_rs::run::read_constraint_list::{closure#1} +FNDA:0,minion_rs::run::read_var::{closure#0} +FNDA:0,minion_rs::run::convert_model_to_raw::{closure#0} +FNDA:0,minion_rs::run::convert_model_to_raw::{closure#3} +FNDA:1,minion_rs::run::convert_model_to_raw +FNDA:0,minion_rs::run::read_list +FNDA:0,minion_rs::run::run_minion::{closure#0} +FNDA:1,minion_rs::run::read_var::{closure#0} +FNDA:0,minion_rs::run::convert_model_to_raw::{closure#2} +FNDA:1,minion_rs::run::read_constraint_list +FNDA:0,minion_rs::run::read_var::{closure#1} +FNDA:0,minion_rs::run::read_list +FNDA:0,minion_rs::run::run_minion +FNDA:0,minion_rs::run::read_2_vars +FNDA:1,minion_rs::run::convert_model_to_raw::{closure#3} +FNDA:1,rust_out::main::_doctest_main_solvers_minion_src_run_rs_28_0::callback +FNDA:0,minion_rs::run::run_minion::{closure#0} +FNDA:0,minion_rs::run::read_constant_list +FNDA:0,minion_rs::run::convert_model_to_raw +FNDA:1,minion_rs::run::read_constant +FNDA:0,minion_rs::run::read_constant +FNDA:0,minion_rs::run::read_constraint_list::{closure#1} +FNDA:1,rust_out::main +FNDA:1,minion_rs::run::read_constant_list::{closure#0} +FNDA:1,minion_rs::run::read_list +FNDA:0,minion_rs::run::read_list::{closure#1} +FNDA:0,minion_rs::run::convert_model_to_raw::{closure#1} +FNDA:0,minion_rs::run::read_2_vars::{closure#1} +FNDA:0,minion_rs::run::read_2_vars::{closure#1} +FNDA:0,minion_rs::run::read_2_vars::{closure#0} +FNDA:0,minion_rs::run::read_constraint_list::{closure#0} +FNDA:0,minion_rs::run::run_minion +FNDA:0,minion_rs::run::read_list::{closure#1} +FNDA:0,minion_rs::run::read_constraint +FNDA:0,minion_rs::run::read_2_vars +FNDA:1,minion_rs::run::read_constant_list +FNDA:0,minion_rs::run::read_constant_list +FNDA:0,minion_rs::run::read_list::{closure#1} +FNDA:1,rust_out::main::_doctest_main_solvers_minion_src_run_rs_28_0 +FNDA:0,minion_rs::run::read_2_vars +FNDA:0,minion_rs::run::read_var +FNDA:0,minion_rs::run::constraint_add_args +FNDA:0,minion_rs::run::read_constraint::{closure#0} +FNDA:0,minion_rs::run::constraint_add_args +FNDA:0,minion_rs::run::convert_model_to_raw::{closure#3} +FNDA:1,minion_rs::run::read_constraint +FNDA:0,minion_rs::run::read_var +FNDA:0,minion_rs::run::read_2_vars::{closure#1} +FNDA:0,minion_rs::run::read_constraint +FNDA:1,minion_rs::run::read_constraint_list::{closure#0} +FNDA:1,minion_rs::run::read_list::{closure#0} +FNDA:1,minion_rs::run::get_constraint_type +FNDA:0,minion_rs::run::convert_model_to_raw +FNDA:1,run_callback +FNDA:0,minion_rs::run::read_constant_list::{closure#0} +FNDA:0,minion_rs::run::read_2_vars::{closure#0} +FNDA:1,minion_rs::run::convert_model_to_raw::{closure#0} +FNF:82 +FNH:24 +BRF:0 +BRH:0 +DA:29,1 +DA:30,1 +DA:31,1 +DA:32,1 +DA:33,1 +DA:34,1 +DA:35,1 +DA:36,1 +DA:37,1 +DA:38,1 +DA:39,1 +DA:40,1 +DA:41,1 +DA:42,1 +DA:43,1 +DA:44,1 +DA:45,1 +DA:46,1 +DA:47,1 +DA:48,1 +DA:49,1 +DA:50,1 +DA:51,1 +DA:52,1 +DA:53,1 +DA:54,1 +DA:55,1 +DA:56,1 +DA:57,1 +DA:58,1 +DA:59,1 +DA:60,1 +DA:61,1 +DA:62,1 +DA:63,1 +DA:64,1 +DA:65,1 +DA:66,1 +DA:67,1 +DA:68,1 +DA:69,1 +DA:70,1 +DA:71,1 +DA:72,1 +DA:73,1 +DA:74,1 +DA:75,1 +DA:76,1 +DA:77,1 +DA:78,1 +DA:79,1 +DA:80,1 +DA:81,1 +DA:82,1 +DA:83,1 +DA:84,1 +DA:85,1 +DA:86,1 +DA:87,1 +DA:88,1 +DA:89,1 +DA:90,1 +DA:91,1 +DA:92,1 +DA:93,1 +DA:94,1 +DA:95,1 +DA:96,1 +DA:97,1 +DA:98,1 +DA:99,1 +DA:100,1 +DA:101,1 +DA:102,1 +DA:103,1 +DA:104,1 +DA:105,1 +DA:119,912 +DA:120,912 +DA:121,912 +DA:122,912 +DA:123,912 +DA:124,912 +DA:125,912 +DA:126,912 +DA:127,912 +DA:128,0 +DA:129,912 +DA:131,912 +DA:132,912 +DA:133,0 +DA:136,912 +DA:137,0 +DA:138,912 +DA:139,912 +DA:140,912 +DA:141,912 +DA:143,2508 +DA:144,2508 +DA:145,2508 +DA:146,2508 +DA:147,2508 +DA:150,912 +DA:151,0 +DA:152,912 +DA:154,912 +DA:162,285 +DA:163,285 +DA:164,285 +DA:165,285 +DA:166,285 +DA:167,285 +DA:168,285 +DA:169,285 +DA:170,285 +DA:171,285 +DA:172,285 +DA:173,285 +DA:174,285 +DA:175,285 +DA:176,285 +DA:177,285 +DA:178,285 +DA:179,285 +DA:181,285 +DA:182,285 +DA:183,285 +DA:184,285 +DA:185,285 +DA:186,285 +DA:187,285 +DA:188,285 +DA:189,285 +DA:190,285 +DA:191,285 +DA:192,285 +DA:193,285 +DA:194,285 +DA:195,285 +DA:196,285 +DA:197,285 +DA:198,285 +DA:199,0 +DA:202,285 +DA:204,285 +DA:205,285 +DA:206,285 +DA:207,285 +DA:208,285 +DA:209,285 +DA:210,285 +DA:211,285 +DA:212,285 +DA:213,285 +DA:214,285 +DA:215,285 +DA:216,285 +DA:217,285 +DA:218,285 +DA:219,285 +DA:220,285 +DA:221,285 +DA:222,285 +DA:223,285 +DA:224,285 +DA:225,285 +DA:226,285 +DA:228,760 +DA:229,760 +DA:230,0 +DA:231,0 +DA:232,0 +DA:233,0 +DA:234,760 +DA:236,760 +DA:237,760 +DA:238,760 +DA:239,760 +DA:241,760 +DA:242,570 +DA:243,190 +DA:244,0 +DA:245,0 +DA:247,760 +DA:248,760 +DA:249,760 +DA:250,760 +DA:251,760 +DA:252,760 +DA:253,760 +DA:254,760 +DA:255,760 +DA:256,760 +DA:257,760 +DA:258,760 +DA:259,760 +DA:260,760 +DA:261,760 +DA:262,760 +DA:263,760 +DA:264,760 +DA:265,760 +DA:268,285 +DA:269,285 +DA:270,285 +DA:271,285 +DA:272,285 +DA:273,285 +DA:279,1273 +DA:284,988 +DA:285,988 +DA:286,988 +DA:287,988 +DA:288,988 +DA:289,988 +DA:290,988 +DA:293,285 +DA:294,285 +DA:296,1805 +DA:297,1805 +DA:298,76 +DA:299,95 +DA:300,1140 +DA:301,0 +DA:302,0 +DA:303,0 +DA:304,0 +DA:305,0 +DA:306,0 +DA:307,0 +DA:308,0 +DA:309,0 +DA:310,0 +DA:311,0 +DA:312,0 +DA:313,0 +DA:314,0 +DA:315,19 +DA:316,0 +DA:317,0 +DA:318,399 +DA:319,0 +DA:320,38 +DA:321,0 +DA:322,0 +DA:323,0 +DA:324,0 +DA:325,0 +DA:326,0 +DA:327,0 +DA:328,0 +DA:329,0 +DA:330,0 +DA:331,0 +DA:332,0 +DA:333,0 +DA:334,0 +DA:335,0 +DA:336,0 +DA:337,0 +DA:338,0 +DA:339,0 +DA:340,0 +DA:341,0 +DA:342,0 +DA:343,0 +DA:344,0 +DA:345,0 +DA:346,0 +DA:347,0 +DA:348,0 +DA:349,0 +DA:350,0 +DA:351,0 +DA:352,0 +DA:353,0 +DA:354,0 +DA:355,0 +DA:357,0 +DA:360,0 +DA:362,0 +DA:363,0 +DA:364,0 +DA:365,0 +DA:366,38 +DA:367,0 +DA:368,0 +DA:369,0 +DA:370,0 +DA:371,0 +DA:372,0 +DA:373,0 +DA:374,0 +DA:377,0 +DA:378,0 +DA:379,0 +DA:380,0 +DA:382,1805 +DA:384,1805 +DA:385,1805 +DA:386,1805 +DA:387,1805 +DA:388,1805 +DA:389,1805 +DA:390,76 +DA:391,76 +DA:392,76 +DA:393,76 +DA:395,95 +DA:396,95 +DA:397,95 +DA:398,95 +DA:400,1140 +DA:401,1140 +DA:402,1140 +DA:403,1140 +DA:404,1140 +DA:406,0 +DA:407,0 +DA:408,0 +DA:409,0 +DA:411,0 +DA:412,0 +DA:413,0 +DA:414,0 +DA:416,0 +DA:417,0 +DA:418,0 +DA:419,0 +DA:421,0 +DA:422,0 +DA:423,0 +DA:424,0 +DA:426,0 +DA:427,0 +DA:428,0 +DA:429,0 +DA:431,0 +DA:432,0 +DA:433,0 +DA:434,0 +DA:436,0 +DA:437,0 +DA:438,0 +DA:439,0 +DA:441,0 +DA:442,0 +DA:443,0 +DA:444,0 +DA:446,0 +DA:447,0 +DA:448,0 +DA:449,0 +DA:450,0 +DA:452,0 +DA:453,0 +DA:454,0 +DA:455,0 +DA:456,0 +DA:458,0 +DA:459,0 +DA:460,0 +DA:462,0 +DA:463,0 +DA:464,0 +DA:466,0 +DA:467,0 +DA:468,0 +DA:470,0 +DA:471,0 +DA:472,0 +DA:473,0 +DA:475,19 +DA:476,19 +DA:477,19 +DA:478,19 +DA:480,0 +DA:481,0 +DA:482,0 +DA:483,0 +DA:485,0 +DA:486,0 +DA:487,0 +DA:489,399 +DA:490,399 +DA:491,399 +DA:493,0 +DA:494,0 +DA:495,0 +DA:497,38 +DA:498,38 +DA:499,38 +DA:501,0 +DA:502,0 +DA:503,0 +DA:504,0 +DA:506,0 +DA:507,0 +DA:508,0 +DA:509,0 +DA:511,0 +DA:512,0 +DA:513,0 +DA:514,0 +DA:516,0 +DA:517,0 +DA:518,0 +DA:519,0 +DA:520,0 +DA:522,0 +DA:523,0 +DA:524,0 +DA:525,0 +DA:526,0 +DA:528,0 +DA:529,0 +DA:530,0 +DA:531,0 +DA:532,0 +DA:569,38 +DA:570,38 +DA:571,38 +DA:572,38 +DA:582,0 +DA:583,0 +DA:584,0 +DA:585,0 +DA:588,0 +DA:590,1805 +DA:594,209 +DA:595,209 +DA:596,209 +DA:597,209 +DA:598,209 +DA:599,209 +DA:600,798 +DA:601,589 +DA:602,589 +DA:603,589 +DA:604,0 +DA:605,0 +DA:606,0 +DA:607,0 +DA:608,589 +DA:609,589 +DA:611,0 +DA:614,589 +DA:617,209 +DA:618,209 +DA:619,209 +DA:620,209 +DA:622,2508 +DA:623,2508 +DA:624,2508 +DA:625,2508 +DA:626,2508 +DA:627,2508 +DA:628,2508 +DA:629,2242 +DA:630,2242 +DA:631,0 +DA:632,0 +DA:633,0 +DA:634,0 +DA:635,2242 +DA:636,2242 +DA:638,266 +DA:641,2508 +DA:642,2508 +DA:643,2508 +DA:644,2508 +DA:645,2508 +DA:647,0 +DA:648,0 +DA:649,0 +DA:650,0 +DA:651,0 +DA:652,0 +DA:653,0 +DA:654,0 +DA:655,0 +DA:656,0 +DA:657,0 +DA:658,0 +DA:659,0 +DA:660,0 +DA:661,0 +DA:663,0 +DA:665,0 +DA:666,0 +DA:667,0 +DA:668,0 +DA:669,0 +DA:670,0 +DA:671,0 +DA:672,0 +DA:673,0 +DA:675,0 +DA:680,0 +DA:681,0 +DA:682,0 +DA:684,1140 +DA:685,1140 +DA:686,1140 +DA:687,1140 +DA:688,1140 +DA:689,1140 +DA:690,0 +DA:691,0 +DA:692,0 +DA:693,0 +DA:695,1140 +DA:696,1140 +DA:697,1140 +DA:698,1140 +DA:700,38 +DA:701,38 +DA:702,38 +DA:703,38 +DA:704,38 +DA:706,38 +DA:707,38 +DA:708,0 +DA:709,19 +DA:710,19 +DA:712,0 +DA:713,0 +DA:715,38 +DA:718,38 +DA:719,38 +DA:720,38 +DA:725,19 +DA:726,19 +DA:727,19 +DA:728,19 +DA:729,19 +DA:730,19 +DA:731,19 +DA:732,19 +DA:733,19 +DA:734,19 +DA:735,19 +DA:737,19 +DA:738,19 +DA:739,19 +DA:741,399 +DA:742,399 +DA:743,399 +DA:744,399 +DA:745,399 +DA:746,399 +DA:747,399 +DA:748,399 +DA:749,798 +DA:750,798 +DA:751,798 +DA:752,798 +DA:753,798 +DA:754,798 +DA:755,798 +DA:756,798 +DA:759,399 +DA:760,399 +DA:761,399 +LF:564 +LH:341 +end_of_record +SF:crates/uniplate_derive/src/utils/generate.rs +FN:72,uniplate_derive::utils::generate::get_clone +FN:9,uniplate_derive::utils::generate::get_fill +FN:146,uniplate_derive::utils::generate::generate_field_idents::{closure#0} +FN:146,uniplate_derive::utils::generate::generate_field_idents::{closure#0} +FN:158,uniplate_derive::utils::generate::generate_field_clones::{closure#0} +FN:142,uniplate_derive::utils::generate::generate_field_idents +FN:146,uniplate_derive::utils::generate::generate_field_idents::{closure#0} +FN:142,uniplate_derive::utils::generate::generate_field_idents +FN:9,uniplate_derive::utils::generate::get_fill +FN:154,uniplate_derive::utils::generate::generate_field_clones +FN:154,uniplate_derive::utils::generate::generate_field_clones +FN:72,uniplate_derive::utils::generate::get_clone +FN:134,uniplate_derive::utils::generate::get_field_name +FN:72,uniplate_derive::utils::generate::get_clone +FN:169,uniplate_derive::utils::generate::generate_field_fills +FN:134,uniplate_derive::utils::generate::get_field_name +FN:134,uniplate_derive::utils::generate::get_field_name +FN:169,uniplate_derive::utils::generate::generate_field_fills +FN:177,uniplate_derive::utils::generate::generate_field_fills::{closure#0} +FN:142,uniplate_derive::utils::generate::generate_field_idents +FN:158,uniplate_derive::utils::generate::generate_field_clones::{closure#0} +FN:9,uniplate_derive::utils::generate::get_fill +FN:177,uniplate_derive::utils::generate::generate_field_fills::{closure#0} +FN:146,uniplate_derive::utils::generate::generate_field_idents::{closure#0} +FN:177,uniplate_derive::utils::generate::generate_field_fills::{closure#0} +FN:169,uniplate_derive::utils::generate::generate_field_fills +FN:142,uniplate_derive::utils::generate::generate_field_idents +FN:9,uniplate_derive::utils::generate::get_fill +FN:158,uniplate_derive::utils::generate::generate_field_clones::{closure#0} +FN:169,uniplate_derive::utils::generate::generate_field_fills +FN:134,uniplate_derive::utils::generate::get_field_name +FN:154,uniplate_derive::utils::generate::generate_field_clones +FN:158,uniplate_derive::utils::generate::generate_field_clones::{closure#0} +FN:177,uniplate_derive::utils::generate::generate_field_fills::{closure#0} +FN:154,uniplate_derive::utils::generate::generate_field_clones +FN:72,uniplate_derive::utils::generate::get_clone +FNDA:1,uniplate_derive::utils::generate::get_clone +FNDA:1,uniplate_derive::utils::generate::get_fill +FNDA:0,uniplate_derive::utils::generate::generate_field_idents::{closure#0} +FNDA:0,uniplate_derive::utils::generate::generate_field_idents::{closure#0} +FNDA:0,uniplate_derive::utils::generate::generate_field_clones::{closure#0} +FNDA:0,uniplate_derive::utils::generate::generate_field_idents +FNDA:1,uniplate_derive::utils::generate::generate_field_idents::{closure#0} +FNDA:1,uniplate_derive::utils::generate::generate_field_idents +FNDA:0,uniplate_derive::utils::generate::get_fill +FNDA:0,uniplate_derive::utils::generate::generate_field_clones +FNDA:1,uniplate_derive::utils::generate::generate_field_clones +FNDA:1,uniplate_derive::utils::generate::get_clone +FNDA:1,uniplate_derive::utils::generate::get_field_name +FNDA:0,uniplate_derive::utils::generate::get_clone +FNDA:1,uniplate_derive::utils::generate::generate_field_fills +FNDA:1,uniplate_derive::utils::generate::get_field_name +FNDA:0,uniplate_derive::utils::generate::get_field_name +FNDA:0,uniplate_derive::utils::generate::generate_field_fills +FNDA:0,uniplate_derive::utils::generate::generate_field_fills::{closure#0} +FNDA:1,uniplate_derive::utils::generate::generate_field_idents +FNDA:1,uniplate_derive::utils::generate::generate_field_clones::{closure#0} +FNDA:0,uniplate_derive::utils::generate::get_fill +FNDA:0,uniplate_derive::utils::generate::generate_field_fills::{closure#0} +FNDA:1,uniplate_derive::utils::generate::generate_field_idents::{closure#0} +FNDA:1,uniplate_derive::utils::generate::generate_field_fills::{closure#0} +FNDA:0,uniplate_derive::utils::generate::generate_field_fills +FNDA:0,uniplate_derive::utils::generate::generate_field_idents +FNDA:1,uniplate_derive::utils::generate::get_fill +FNDA:1,uniplate_derive::utils::generate::generate_field_clones::{closure#0} +FNDA:1,uniplate_derive::utils::generate::generate_field_fills +FNDA:0,uniplate_derive::utils::generate::get_field_name +FNDA:1,uniplate_derive::utils::generate::generate_field_clones +FNDA:0,uniplate_derive::utils::generate::generate_field_clones::{closure#0} +FNDA:1,uniplate_derive::utils::generate::generate_field_fills::{closure#0} +FNDA:0,uniplate_derive::utils::generate::generate_field_clones +FNDA:0,uniplate_derive::utils::generate::get_clone +FNF:36 +FNH:18 +BRF:0 +BRH:0 +DA:9,481 +DA:10,481 +DA:11,481 +DA:12,481 +DA:13,481 +DA:14,481 +DA:15,481 +DA:17,356 +DA:19,176 +DA:20,176 +DA:21,176 +DA:23,123 +DA:24,123 +DA:25,123 +DA:26,123 +DA:27,123 +DA:28,123 +DA:30,54 +DA:31,54 +DA:32,54 +DA:33,54 +DA:34,54 +DA:35,54 +DA:36,54 +DA:37,54 +DA:38,54 +DA:39,54 +DA:40,54 +DA:41,54 +DA:43,3 +DA:44,3 +DA:46,6 +DA:47,6 +DA:48,6 +DA:49,6 +DA:50,6 +DA:51,6 +DA:52,6 +DA:53,6 +DA:55,3 +DA:56,3 +DA:57,3 +DA:60,0 +DA:62,0 +DA:64,125 +DA:66,125 +DA:67,125 +DA:68,125 +DA:69,481 +DA:72,481 +DA:73,481 +DA:74,481 +DA:75,481 +DA:76,481 +DA:77,481 +DA:79,356 +DA:81,176 +DA:82,176 +DA:83,176 +DA:85,123 +DA:86,123 +DA:87,123 +DA:88,123 +DA:89,123 +DA:90,123 +DA:92,54 +DA:93,54 +DA:94,54 +DA:95,54 +DA:96,54 +DA:97,54 +DA:98,54 +DA:99,54 +DA:100,54 +DA:102,3 +DA:103,3 +DA:105,6 +DA:107,6 +DA:108,6 +DA:109,6 +DA:110,6 +DA:111,6 +DA:112,6 +DA:113,1 +DA:114,5 +DA:118,3 +DA:119,3 +DA:120,3 +DA:124,0 +DA:126,0 +DA:128,125 +DA:130,125 +DA:131,481 +DA:134,1192 +DA:135,1192 +DA:136,1192 +DA:137,0 +DA:139,1192 +DA:142,252 +DA:143,252 +DA:144,252 +DA:145,252 +DA:146,596 +DA:147,596 +DA:148,596 +DA:149,596 +DA:150,252 +DA:151,252 +DA:154,126 +DA:155,126 +DA:156,126 +DA:157,126 +DA:158,298 +DA:159,298 +DA:160,298 +DA:161,298 +DA:162,298 +DA:163,298 +DA:164,298 +DA:165,126 +DA:166,126 +DA:169,126 +DA:170,126 +DA:171,126 +DA:172,126 +DA:173,126 +DA:174,126 +DA:175,126 +DA:176,126 +DA:177,298 +DA:178,298 +DA:179,298 +DA:180,298 +DA:181,298 +DA:182,298 +DA:183,298 +DA:184,126 +DA:185,126 +LF:138 +LH:133 +end_of_record +SF:crates/conjure_core/src/rule_engine/mod.rs +FN:213,conjure_core::rule_engine::get_rule_sets_for_solver_family +FN:222,conjure_core::rule_engine::get_rule_sets_for_solver_family::{closure#0}::{closure#0} +FN:160,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_154_0::CONJURE_GEN_RULE_SET_ANOTHERRULESET::__typecheck +FN:172,conjure_core::rule_engine::get_rule_sets +FN:218,conjure_core::rule_engine::get_rule_sets_for_solver_family::{closure#0} +FN:222,conjure_core::rule_engine::get_rule_sets_for_solver_family::{closure#0}::{closure#0} +FN:145,conjure_core::rule_engine::get_rule_by_name +FN:117,conjure_core::rule_engine::get_rules +FN:206,rust_out::main +FN:40,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_33_0::CONJURE_GEN_RULE_IDENTITY::__typecheck::{closure#0}::{closure#0} +FN:103,rust_out::CONJURE_GEN_RULE_IDENTITY::__typecheck::{closure#0} +FN:103,rust_out::CONJURE_GEN_RULE_IDENTITY::__typecheck +FN:103,rust_out::CONJURE_GEN_RULE_IDENTITY::__typecheck::{closure#0}::{closure#0} +FN:193,conjure_core::rule_engine::get_rule_set_by_name +FN:63,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_59_0::CONJURE_GEN_RULE_SET_MYRULESET::__typecheck +FN:63,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_59_0::CONJURE_GEN_RULE_SET_MYRULESET::__typecheck::{closure#0}::{closure#0} +FN:34,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_33_0 +FN:160,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_154_0::CONJURE_GEN_RULE_SET_ANOTHERRULESET::__typecheck::{closure#0}::{closure#0} +FN:159,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_154_0::CONJURE_GEN_RULE_SET_MYRULESET::__typecheck +FN:159,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_154_0::CONJURE_GEN_RULE_SET_MYRULESET::__typecheck::{closure#0} +FN:146,conjure_core::rule_engine::get_rule_by_name::{closure#0} +FN:172,conjure_core::rule_engine::get_rule_sets +FN:41,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_33_0::identity +FN:213,conjure_core::rule_engine::get_rule_sets_for_solver_family +FN:172,conjure_core::rule_engine::get_rule_sets +FN:117,conjure_core::rule_engine::get_rules +FN:218,conjure_core::rule_engine::get_rule_sets_for_solver_family::{closure#0} +FN:40,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_33_0::CONJURE_GEN_RULE_IDENTITY::__typecheck +FN:193,conjure_core::rule_engine::get_rule_set_by_name +FN:145,conjure_core::rule_engine::get_rule_by_name +FN:155,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_154_0 +FN:206,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_205_0 +FN:193,conjure_core::rule_engine::get_rule_set_by_name +FN:196,conjure_core::rule_engine::get_rule_set_by_name::{closure#0} +FN:146,conjure_core::rule_engine::get_rule_by_name::{closure#0} +FN:185,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_180_0::CONJURE_GEN_RULE_SET_MYRULESET::__typecheck +FN:181,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_180_0 +FN:185,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_180_0::CONJURE_GEN_RULE_SET_MYRULESET::__typecheck::{closure#0} +FN:60,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_59_0 +FN:146,conjure_core::rule_engine::get_rule_by_name::{closure#0} +FN:213,conjure_core::rule_engine::get_rule_sets_for_solver_family +FN:218,conjure_core::rule_engine::get_rule_sets_for_solver_family::{closure#0} +FN:222,conjure_core::rule_engine::get_rule_sets_for_solver_family::{closure#0}::{closure#0} +FN:160,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_154_0::CONJURE_GEN_RULE_SET_ANOTHERRULESET::__typecheck::{closure#0} +FN:196,conjure_core::rule_engine::get_rule_set_by_name::{closure#0} +FN:63,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_59_0::CONJURE_GEN_RULE_SET_MYRULESET::__typecheck::{closure#0} +FN:185,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_180_0::CONJURE_GEN_RULE_SET_MYRULESET::__typecheck::{closure#0}::{closure#0} +FN:104,rust_out::identity +FN:40,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_33_0::CONJURE_GEN_RULE_IDENTITY::__typecheck::{closure#0} +FN:117,conjure_core::rule_engine::get_rules +FN:159,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_154_0::CONJURE_GEN_RULE_SET_MYRULESET::__typecheck::{closure#0}::{closure#0} +FN:196,conjure_core::rule_engine::get_rule_set_by_name::{closure#0} +FN:145,conjure_core::rule_engine::get_rule_by_name +FNDA:1,conjure_core::rule_engine::get_rule_sets_for_solver_family +FNDA:1,conjure_core::rule_engine::get_rule_sets_for_solver_family::{closure#0}::{closure#0} +FNDA:0,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_154_0::CONJURE_GEN_RULE_SET_ANOTHERRULESET::__typecheck +FNDA:0,conjure_core::rule_engine::get_rule_sets +FNDA:0,conjure_core::rule_engine::get_rule_sets_for_solver_family::{closure#0} +FNDA:0,conjure_core::rule_engine::get_rule_sets_for_solver_family::{closure#0}::{closure#0} +FNDA:0,conjure_core::rule_engine::get_rule_by_name +FNDA:0,conjure_core::rule_engine::get_rules +FNDA:1,rust_out::main +FNDA:0,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_33_0::CONJURE_GEN_RULE_IDENTITY::__typecheck::{closure#0}::{closure#0} +FNDA:0,rust_out::CONJURE_GEN_RULE_IDENTITY::__typecheck::{closure#0} +FNDA:0,rust_out::CONJURE_GEN_RULE_IDENTITY::__typecheck +FNDA:0,rust_out::CONJURE_GEN_RULE_IDENTITY::__typecheck::{closure#0}::{closure#0} +FNDA:1,conjure_core::rule_engine::get_rule_set_by_name +FNDA:0,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_59_0::CONJURE_GEN_RULE_SET_MYRULESET::__typecheck +FNDA:0,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_59_0::CONJURE_GEN_RULE_SET_MYRULESET::__typecheck::{closure#0}::{closure#0} +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_33_0 +FNDA:0,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_154_0::CONJURE_GEN_RULE_SET_ANOTHERRULESET::__typecheck::{closure#0}::{closure#0} +FNDA:0,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_154_0::CONJURE_GEN_RULE_SET_MYRULESET::__typecheck +FNDA:0,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_154_0::CONJURE_GEN_RULE_SET_MYRULESET::__typecheck::{closure#0} +FNDA:0,conjure_core::rule_engine::get_rule_by_name::{closure#0} +FNDA:1,conjure_core::rule_engine::get_rule_sets +FNDA:0,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_33_0::identity +FNDA:0,conjure_core::rule_engine::get_rule_sets_for_solver_family +FNDA:0,conjure_core::rule_engine::get_rule_sets +FNDA:0,conjure_core::rule_engine::get_rules +FNDA:1,conjure_core::rule_engine::get_rule_sets_for_solver_family::{closure#0} +FNDA:0,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_33_0::CONJURE_GEN_RULE_IDENTITY::__typecheck +FNDA:0,conjure_core::rule_engine::get_rule_set_by_name +FNDA:0,conjure_core::rule_engine::get_rule_by_name +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_154_0 +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_205_0 +FNDA:0,conjure_core::rule_engine::get_rule_set_by_name +FNDA:0,conjure_core::rule_engine::get_rule_set_by_name::{closure#0} +FNDA:1,conjure_core::rule_engine::get_rule_by_name::{closure#0} +FNDA:0,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_180_0::CONJURE_GEN_RULE_SET_MYRULESET::__typecheck +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_180_0 +FNDA:0,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_180_0::CONJURE_GEN_RULE_SET_MYRULESET::__typecheck::{closure#0} +FNDA:1,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_59_0 +FNDA:0,conjure_core::rule_engine::get_rule_by_name::{closure#0} +FNDA:0,conjure_core::rule_engine::get_rule_sets_for_solver_family +FNDA:0,conjure_core::rule_engine::get_rule_sets_for_solver_family::{closure#0} +FNDA:0,conjure_core::rule_engine::get_rule_sets_for_solver_family::{closure#0}::{closure#0} +FNDA:0,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_154_0::CONJURE_GEN_RULE_SET_ANOTHERRULESET::__typecheck::{closure#0} +FNDA:0,conjure_core::rule_engine::get_rule_set_by_name::{closure#0} +FNDA:0,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_59_0::CONJURE_GEN_RULE_SET_MYRULESET::__typecheck::{closure#0} +FNDA:0,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_180_0::CONJURE_GEN_RULE_SET_MYRULESET::__typecheck::{closure#0}::{closure#0} +FNDA:0,rust_out::identity +FNDA:0,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_33_0::CONJURE_GEN_RULE_IDENTITY::__typecheck::{closure#0} +FNDA:1,conjure_core::rule_engine::get_rules +FNDA:0,rust_out::main::_doctest_main_crates_conjure_core_src_rule_engine_mod_rs_154_0::CONJURE_GEN_RULE_SET_MYRULESET::__typecheck::{closure#0}::{closure#0} +FNDA:1,conjure_core::rule_engine::get_rule_set_by_name::{closure#0} +FNDA:1,conjure_core::rule_engine::get_rule_by_name +FNF:53 +FNH:15 +BRF:0 +BRH:0 +DA:34,1 +DA:35,1 +DA:36,1 +DA:37,1 +DA:38,1 +DA:39,1 +DA:40,1 +DA:41,1 +DA:42,0 +DA:43,0 +DA:44,1 +DA:60,1 +DA:61,1 +DA:62,1 +DA:63,1 +DA:64,1 +DA:103,0 +DA:104,0 +DA:105,0 +DA:106,0 +DA:108,1 +DA:109,1 +DA:110,1 +DA:117,615 +DA:118,615 +DA:119,615 +DA:132,0 +DA:133,0 +DA:134,0 +DA:135,0 +DA:137,1 +DA:138,1 +DA:139,1 +DA:145,375 +DA:146,6570 +DA:147,375 +DA:155,1 +DA:156,1 +DA:157,1 +DA:158,1 +DA:159,1 +DA:160,1 +DA:161,1 +DA:162,1 +DA:163,1 +DA:172,465 +DA:173,465 +DA:174,465 +DA:181,1 +DA:182,1 +DA:183,1 +DA:184,1 +DA:185,1 +DA:186,1 +DA:187,1 +DA:188,1 +DA:193,255 +DA:194,255 +DA:195,255 +DA:196,615 +DA:197,255 +DA:198,255 +DA:206,1 +DA:207,1 +DA:208,1 +DA:209,1 +DA:210,1 +DA:211,1 +DA:212,1 +DA:213,183 +DA:214,195 +DA:215,195 +DA:216,195 +DA:217,195 +DA:218,780 +DA:219,780 +DA:220,780 +DA:221,780 +DA:222,780 +DA:223,780 +DA:224,195 +DA:225,195 +DA:226,195 +LF:83 +LH:73 +end_of_record +SF:crates/uniplate_derive/src/lib.rs +FN:157,uniplate_derive::derive::{closure#1} +FN:12,uniplate_derive::generate_match_pattern +FN:110,rust_out::main +FN:12,uniplate_derive::generate_match_pattern +FN:157,uniplate_derive::derive::{closure#1} +FN:127,uniplate_derive::derive +FN:157,uniplate_derive::derive::{closure#1} +FN:28,uniplate_derive::generate_variant_children_match_arm +FN:53,uniplate_derive::generate_variant_context_match_arm +FN:127,uniplate_derive::derive +FN:53,uniplate_derive::generate_variant_context_match_arm +FN:114,::uniplate::{closure#0} +FN:138,uniplate_derive::derive::{closure#0} +FN:110,rust_out::main::_doctest_main_crates_uniplate_derive_src_lib_rs_109_0 +FN:114,::uniplate +FN:127,uniplate_derive::derive +FN:28,uniplate_derive::generate_variant_children_match_arm +FN:138,uniplate_derive::derive::{closure#0} +FN:114,::uniplate::{closure#3} +FN:138,uniplate_derive::derive::{closure#0} +FN:157,uniplate_derive::derive::{closure#1} +FN:12,uniplate_derive::generate_match_pattern +FN:114,::uniplate::{closure#2} +FN:28,uniplate_derive::generate_variant_children_match_arm +FN:138,uniplate_derive::derive::{closure#0} +FN:114,::uniplate::{closure#1} +FN:12,uniplate_derive::generate_match_pattern +FN:28,uniplate_derive::generate_variant_children_match_arm +FN:53,uniplate_derive::generate_variant_context_match_arm +FN:53,uniplate_derive::generate_variant_context_match_arm +FN:127,uniplate_derive::derive +FNDA:1,uniplate_derive::derive::{closure#1} +FNDA:0,uniplate_derive::generate_match_pattern +FNDA:1,rust_out::main +FNDA:1,uniplate_derive::generate_match_pattern +FNDA:0,uniplate_derive::derive::{closure#1} +FNDA:1,uniplate_derive::derive +FNDA:1,uniplate_derive::derive::{closure#1} +FNDA:0,uniplate_derive::generate_variant_children_match_arm +FNDA:0,uniplate_derive::generate_variant_context_match_arm +FNDA:0,uniplate_derive::derive +FNDA:1,uniplate_derive::generate_variant_context_match_arm +FNDA:1,::uniplate::{closure#0} +FNDA:0,uniplate_derive::derive::{closure#0} +FNDA:1,rust_out::main::_doctest_main_crates_uniplate_derive_src_lib_rs_109_0 +FNDA:1,::uniplate +FNDA:1,uniplate_derive::derive +FNDA:1,uniplate_derive::generate_variant_children_match_arm +FNDA:0,uniplate_derive::derive::{closure#0} +FNDA:0,::uniplate::{closure#3} +FNDA:1,uniplate_derive::derive::{closure#0} +FNDA:0,uniplate_derive::derive::{closure#1} +FNDA:1,uniplate_derive::generate_match_pattern +FNDA:0,::uniplate::{closure#2} +FNDA:0,uniplate_derive::generate_variant_children_match_arm +FNDA:1,uniplate_derive::derive::{closure#0} +FNDA:0,::uniplate::{closure#1} +FNDA:0,uniplate_derive::generate_match_pattern +FNDA:1,uniplate_derive::generate_variant_children_match_arm +FNDA:0,uniplate_derive::generate_variant_context_match_arm +FNDA:1,uniplate_derive::generate_variant_context_match_arm +FNDA:0,uniplate_derive::derive +FNF:31 +FNH:16 +BRF:0 +BRH:0 +DA:12,252 +DA:13,252 +DA:14,252 +DA:15,252 +DA:16,252 +DA:17,12 +DA:18,12 +DA:19,12 +DA:21,240 +DA:22,240 +DA:23,240 +DA:25,252 +DA:28,126 +DA:29,126 +DA:30,126 +DA:31,126 +DA:33,126 +DA:34,20 +DA:35,20 +DA:36,20 +DA:38,106 +DA:39,106 +DA:40,106 +DA:43,126 +DA:44,126 +DA:45,126 +DA:46,126 +DA:47,126 +DA:48,126 +DA:49,126 +DA:50,126 +DA:53,126 +DA:54,126 +DA:55,126 +DA:56,126 +DA:57,126 +DA:58,126 +DA:59,126 +DA:60,126 +DA:61,6 +DA:62,6 +DA:63,6 +DA:64,6 +DA:65,6 +DA:67,120 +DA:68,120 +DA:69,120 +DA:70,120 +DA:71,120 +DA:72,120 +DA:73,120 +DA:74,120 +DA:75,120 +DA:76,120 +DA:77,120 +DA:78,120 +DA:80,126 +DA:110,1 +DA:111,1 +DA:112,1 +DA:113,1 +DA:114,3 +DA:115,1 +DA:116,1 +DA:117,1 +DA:118,1 +DA:119,1 +DA:120,1 +DA:121,1 +DA:122,1 +DA:123,1 +DA:124,1 +DA:125,1 +DA:127,8 +DA:128,8 +DA:129,8 +DA:130,8 +DA:132,8 +DA:133,0 +DA:134,0 +DA:135,8 +DA:136,8 +DA:137,8 +DA:138,126 +DA:139,8 +DA:141,8 +DA:142,8 +DA:143,8 +DA:144,8 +DA:145,8 +DA:147,8 +DA:151,8 +DA:152,0 +DA:153,0 +DA:154,8 +DA:155,8 +DA:156,8 +DA:157,126 +DA:158,8 +DA:160,8 +DA:161,8 +DA:162,8 +DA:163,8 +DA:164,8 +DA:166,8 +DA:167,8 +DA:168,8 +DA:169,8 +DA:170,8 +DA:171,8 +DA:172,8 +DA:173,8 +DA:174,8 +DA:175,8 +DA:176,8 +DA:177,8 +DA:178,8 +DA:179,8 +DA:180,8 +DA:181,8 +DA:182,8 +DA:183,8 +DA:184,8 +DA:185,8 +DA:186,8 +DA:187,8 +DA:188,8 +DA:189,8 +DA:190,8 +LF:129 +LH:125 +end_of_record +SF:crates/conjure_core/src/stats/mod.rs +FN:17,::new +FN:17,::new +FN:21,::add_solver_run +FN:21,::add_solver_run +FN:17,::new +FN:21,::add_solver_run +FNDA:0,::new +FNDA:0,::new +FNDA:0,::add_solver_run +FNDA:0,::add_solver_run +FNDA:0,::new +FNDA:1,::add_solver_run +FNF:6 +FNH:1 +BRF:0 +BRH:0 +DA:17,0 +DA:18,0 +DA:19,0 +DA:21,135 +DA:22,135 +DA:23,135 +LF:6 +LH:3 +end_of_record +SF:crates/conjure_macros/src/lib.rs +FN:151,rust_out::main::_doctest_main_crates_conjure_macros_src_lib_rs_151_0 +FN:82,conjure_rules_proc_macro::parse_parenthesized:: +FN:47,conjure_rules_proc_macro::register_rule +FN:107,::parse +FN:57,conjure_rules_proc_macro::register_rule::{closure#0} +FN:151,rust_out::main +FN:47,conjure_rules_proc_macro::register_rule +FN:155,conjure_rules_proc_macro::register_rule_set +FN:19,::parse +FN:155,conjure_rules_proc_macro::register_rule_set +FN:155,conjure_rules_proc_macro::register_rule_set +FN:155,conjure_rules_proc_macro::register_rule_set +FN:82,conjure_rules_proc_macro::parse_parenthesized:: +FN:47,conjure_rules_proc_macro::register_rule +FN:19,::parse +FN:35,::parse +FN:35,::parse +FN:82,conjure_rules_proc_macro::parse_parenthesized:: +FN:148,rust_out::main::_doctest_main_crates_conjure_macros_src_lib_rs_148_0 +FN:107,::parse +FN:57,conjure_rules_proc_macro::register_rule::{closure#0} +FN:19,::parse +FN:57,conjure_rules_proc_macro::register_rule::{closure#0} +FN:35,::parse +FN:107,::parse +FN:35,::parse +FN:82,conjure_rules_proc_macro::parse_parenthesized:: +FN:107,::parse +FN:82,conjure_rules_proc_macro::parse_parenthesized::<_> +FN:19,::parse +FN:82,conjure_rules_proc_macro::parse_parenthesized:: +FN:82,conjure_rules_proc_macro::parse_parenthesized:: +FN:57,conjure_rules_proc_macro::register_rule::{closure#0} +FN:47,conjure_rules_proc_macro::register_rule +FNDA:1,rust_out::main::_doctest_main_crates_conjure_macros_src_lib_rs_151_0 +FNDA:1,conjure_rules_proc_macro::parse_parenthesized:: +FNDA:0,conjure_rules_proc_macro::register_rule +FNDA:1,::parse +FNDA:1,conjure_rules_proc_macro::register_rule::{closure#0} +FNDA:1,rust_out::main +FNDA:1,conjure_rules_proc_macro::register_rule +FNDA:0,conjure_rules_proc_macro::register_rule_set +FNDA:0,::parse +FNDA:1,conjure_rules_proc_macro::register_rule_set +FNDA:1,conjure_rules_proc_macro::register_rule_set +FNDA:0,conjure_rules_proc_macro::register_rule_set +FNDA:0,conjure_rules_proc_macro::parse_parenthesized:: +FNDA:1,conjure_rules_proc_macro::register_rule +FNDA:0,::parse +FNDA:0,::parse +FNDA:0,::parse +FNDA:0,conjure_rules_proc_macro::parse_parenthesized:: +FNDA:1,rust_out::main::_doctest_main_crates_conjure_macros_src_lib_rs_148_0 +FNDA:0,::parse +FNDA:1,conjure_rules_proc_macro::register_rule::{closure#0} +FNDA:1,::parse +FNDA:0,conjure_rules_proc_macro::register_rule::{closure#0} +FNDA:1,::parse +FNDA:1,::parse +FNDA:1,::parse +FNDA:1,conjure_rules_proc_macro::parse_parenthesized:: +FNDA:0,::parse +FNDA:0,conjure_rules_proc_macro::parse_parenthesized::<_> +FNDA:1,::parse +FNDA:1,conjure_rules_proc_macro::parse_parenthesized:: +FNDA:1,conjure_rules_proc_macro::parse_parenthesized:: +FNDA:0,conjure_rules_proc_macro::register_rule::{closure#0} +FNDA:0,conjure_rules_proc_macro::register_rule +FNF:34 +FNH:19 +BRF:0 +BRH:0 +DA:19,169 +DA:20,169 +DA:21,169 +DA:22,169 +DA:23,169 +DA:24,169 +DA:25,169 +DA:26,169 +DA:35,171 +DA:36,171 +DA:37,171 +DA:38,171 +DA:39,171 +DA:40,171 +DA:47,171 +DA:48,171 +DA:49,171 +DA:50,171 +DA:51,171 +DA:53,171 +DA:54,171 +DA:55,171 +DA:56,171 +DA:57,171 +DA:58,169 +DA:59,169 +DA:60,169 +DA:61,169 +DA:62,169 +DA:63,171 +DA:64,171 +DA:66,171 +DA:67,171 +DA:68,171 +DA:69,171 +DA:70,171 +DA:71,171 +DA:72,171 +DA:73,171 +DA:74,171 +DA:75,171 +DA:76,171 +DA:77,171 +DA:79,171 +DA:80,171 +DA:82,40 +DA:83,40 +DA:84,40 +DA:86,40 +DA:87,42 +DA:88,29 +DA:89,29 +DA:90,29 +DA:91,27 +DA:92,2 +DA:93,2 +DA:96,40 +DA:97,40 +DA:107,28 +DA:108,28 +DA:109,28 +DA:110,28 +DA:112,28 +DA:113,0 +DA:114,0 +DA:115,0 +DA:116,0 +DA:117,0 +DA:118,0 +DA:119,28 +DA:120,28 +DA:121,28 +DA:122,28 +DA:124,28 +DA:125,16 +DA:126,16 +DA:127,16 +DA:128,16 +DA:129,16 +DA:130,16 +DA:131,12 +DA:132,12 +DA:133,12 +DA:134,12 +DA:136,12 +DA:137,12 +DA:138,12 +DA:139,12 +DA:140,12 +DA:141,12 +DA:142,28 +DA:148,1 +DA:149,1 +DA:150,1 +DA:151,1 +DA:152,1 +DA:153,1 +DA:155,28 +DA:157,28 +DA:158,28 +DA:159,28 +DA:160,28 +DA:161,28 +DA:163,28 +DA:164,28 +DA:166,28 +DA:167,28 +DA:168,28 +DA:170,28 +DA:171,28 +DA:172,28 +DA:174,28 +DA:175,28 +DA:176,28 +DA:177,28 +DA:178,28 +DA:179,28 +DA:180,28 +DA:181,28 +LF:119 +LH:113 +end_of_record +SF:crates/uniplate/src/test_common/paper.rs +FN:45,uniplate::test_common::paper::proptest_stmts +FN:48,uniplate::test_common::paper::proptest_stmts::{closure#0} +FN:46,uniplate::test_common::paper::proptest_stmts::{closure#1} +FN:51,uniplate::test_common::paper::proptest_stmts::{closure#0}::{closure#0} +FN:27,uniplate::test_common::paper::proptest_exprs +FN:37,uniplate::test_common::paper::proptest_exprs::{closure#0}::{closure#2} +FN:35,uniplate::test_common::paper::proptest_exprs::{closure#0}::{closure#1} +FN:33,uniplate::test_common::paper::proptest_exprs::{closure#0}::{closure#0} +FN:30,uniplate::test_common::paper::proptest_exprs::{closure#0} +FN:58,uniplate::test_common::paper::proptest_stmts::{closure#0}::{closure#1} +FN:40,uniplate::test_common::paper::proptest_exprs::{closure#0}::{closure#4} +FN:39,uniplate::test_common::paper::proptest_exprs::{closure#0}::{closure#3} +FNDA:0,uniplate::test_common::paper::proptest_stmts +FNDA:0,uniplate::test_common::paper::proptest_stmts::{closure#0} +FNDA:0,uniplate::test_common::paper::proptest_stmts::{closure#1} +FNDA:0,uniplate::test_common::paper::proptest_stmts::{closure#0}::{closure#0} +FNDA:0,uniplate::test_common::paper::proptest_exprs +FNDA:0,uniplate::test_common::paper::proptest_exprs::{closure#0}::{closure#2} +FNDA:0,uniplate::test_common::paper::proptest_exprs::{closure#0}::{closure#1} +FNDA:0,uniplate::test_common::paper::proptest_exprs::{closure#0}::{closure#0} +FNDA:0,uniplate::test_common::paper::proptest_exprs::{closure#0} +FNDA:0,uniplate::test_common::paper::proptest_stmts::{closure#0}::{closure#1} +FNDA:0,uniplate::test_common::paper::proptest_exprs::{closure#0}::{closure#4} +FNDA:0,uniplate::test_common::paper::proptest_exprs::{closure#0}::{closure#3} +FNF:12 +FNH:0 +BRF:0 +BRH:0 +DA:27,0 +DA:28,0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:34,0 +DA:35,0 +DA:36,0 +DA:37,0 +DA:38,0 +DA:39,0 +DA:40,0 +DA:41,0 +DA:42,0 +DA:43,0 +DA:45,0 +DA:46,0 +DA:47,0 +DA:48,0 +DA:49,0 +DA:50,0 +DA:51,0 +DA:52,0 +DA:53,0 +DA:54,0 +DA:55,0 +DA:56,0 +DA:57,0 +DA:58,0 +DA:59,0 +DA:60,0 +DA:61,0 +DA:62,0 +LF:35 +LH:0 +end_of_record +SF:crates/conjure_core/src/solver/model_modifier.rs +FN:27,<_ as conjure_core::solver::model_modifier::ModelModifier>::add_variable +FN:27,<_ as conjure_core::solver::model_modifier::ModelModifier>::add_variable +FN:27,<_ as conjure_core::solver::model_modifier::ModelModifier>::add_variable +FN:23,<_ as conjure_core::solver::model_modifier::ModelModifier>::add_constraint +FN:23,<_ as conjure_core::solver::model_modifier::ModelModifier>::add_constraint +FN:23,<_ as conjure_core::solver::model_modifier::ModelModifier>::add_constraint +FNDA:0,<_ as conjure_core::solver::model_modifier::ModelModifier>::add_variable +FNDA:0,<_ as conjure_core::solver::model_modifier::ModelModifier>::add_variable +FNDA:0,<_ as conjure_core::solver::model_modifier::ModelModifier>::add_variable +FNDA:0,<_ as conjure_core::solver::model_modifier::ModelModifier>::add_constraint +FNDA:0,<_ as conjure_core::solver::model_modifier::ModelModifier>::add_constraint +FNDA:0,<_ as conjure_core::solver::model_modifier::ModelModifier>::add_constraint +FNF:6 +FNH:0 +BRF:0 +BRH:0 +DA:23,0 +DA:24,0 +DA:25,0 +DA:27,0 +DA:28,0 +DA:29,0 +LF:6 +LH:0 +end_of_record +SF:crates/conjure_core/src/solver/adaptors/minion.rs +FN:77,::new +FN:344,conjure_core::solver::adaptors::minion::_name_to_string +FN:321,conjure_core::solver::adaptors::minion::_read_ref +FN:263,conjure_core::solver::adaptors::minion::read_expr +FN:44,conjure_core::solver::adaptors::minion::minion_rs_callback::{closure#0} +FN:77,::new +FN:135,::solve_mut +FN:93,::solve +FN:155,::get_name +FN:41,conjure_core::solver::adaptors::minion::minion_rs_callback +FN:185,conjure_core::solver::adaptors::minion::_parse_intdomain_var +FN:160,conjure_core::solver::adaptors::minion::parse_vars +FN:310,conjure_core::solver::adaptors::minion::read_var +FN:86,::default +FN:160,conjure_core::solver::adaptors::minion::parse_vars +FN:151,::get_family +FN:310,conjure_core::solver::adaptors::minion::read_var +FN:173,conjure_core::solver::adaptors::minion::parse_var +FN:105,::solve::{closure#0}::{closure#0} +FN:219,conjure_core::solver::adaptors::minion::_parse_booldomain_var +FN:44,conjure_core::solver::adaptors::minion::minion_rs_callback::{closure#0}::{closure#0} +FN:344,conjure_core::solver::adaptors::minion::_name_to_string +FN:44,conjure_core::solver::adaptors::minion::minion_rs_callback::{closure#0} +FN:295,conjure_core::solver::adaptors::minion::read_expr::{closure#0} +FN:105,::solve::{closure#0} +FN:255,conjure_core::solver::adaptors::minion::parse_expr +FN:116,::solve::{closure#1} +FN:334,conjure_core::solver::adaptors::minion::read_const +FN:344,conjure_core::solver::adaptors::minion::_name_to_string +FN:173,conjure_core::solver::adaptors::minion::parse_var +FN:231,conjure_core::solver::adaptors::minion::_try_add_var +FN:231,conjure_core::solver::adaptors::minion::_try_add_var +FN:245,conjure_core::solver::adaptors::minion::parse_exprs +FN:44,conjure_core::solver::adaptors::minion::minion_rs_callback::{closure#0}::{closure#0} +FN:185,conjure_core::solver::adaptors::minion::_parse_intdomain_var +FN:321,conjure_core::solver::adaptors::minion::_read_ref +FN:301,conjure_core::solver::adaptors::minion::read_vars +FN:334,conjure_core::solver::adaptors::minion::read_const +FN:295,conjure_core::solver::adaptors::minion::read_expr::{closure#0} +FN:301,conjure_core::solver::adaptors::minion::read_vars +FN:155,::get_name +FN:173,conjure_core::solver::adaptors::minion::parse_var +FN:77,::new +FN:321,conjure_core::solver::adaptors::minion::_read_ref +FN:135,::solve_mut +FN:105,::solve::{closure#0}::{closure#0} +FN:41,conjure_core::solver::adaptors::minion::minion_rs_callback +FN:263,conjure_core::solver::adaptors::minion::read_expr +FN:219,conjure_core::solver::adaptors::minion::_parse_booldomain_var +FN:151,::get_family +FN:160,conjure_core::solver::adaptors::minion::parse_vars +FN:86,::default +FN:334,conjure_core::solver::adaptors::minion::read_const +FN:263,conjure_core::solver::adaptors::minion::read_expr +FN:245,conjure_core::solver::adaptors::minion::parse_exprs +FN:310,conjure_core::solver::adaptors::minion::read_var +FN:93,::solve +FN:116,::solve::{closure#1} +FN:41,conjure_core::solver::adaptors::minion::minion_rs_callback +FN:143,::load_model +FN:44,conjure_core::solver::adaptors::minion::minion_rs_callback::{closure#0}::{closure#0} +FN:116,::solve::{closure#1} +FN:143,::load_model +FN:105,::solve::{closure#0} +FN:255,conjure_core::solver::adaptors::minion::parse_expr +FN:301,conjure_core::solver::adaptors::minion::read_vars +FN:143,::load_model +FN:295,conjure_core::solver::adaptors::minion::read_expr::{closure#0} +FN:219,conjure_core::solver::adaptors::minion::_parse_booldomain_var +FN:255,conjure_core::solver::adaptors::minion::parse_expr +FN:105,::solve::{closure#0} +FN:245,conjure_core::solver::adaptors::minion::parse_exprs +FN:135,::solve_mut +FN:151,::get_family +FN:86,::default +FN:93,::solve +FN:231,conjure_core::solver::adaptors::minion::_try_add_var +FN:44,conjure_core::solver::adaptors::minion::minion_rs_callback::{closure#0} +FN:185,conjure_core::solver::adaptors::minion::_parse_intdomain_var +FN:155,::get_name +FN:105,::solve::{closure#0}::{closure#0} +FNDA:0,::new +FNDA:1,conjure_core::solver::adaptors::minion::_name_to_string +FNDA:1,conjure_core::solver::adaptors::minion::_read_ref +FNDA:0,conjure_core::solver::adaptors::minion::read_expr +FNDA:0,conjure_core::solver::adaptors::minion::minion_rs_callback::{closure#0} +FNDA:1,::new +FNDA:0,::solve_mut +FNDA:0,::solve +FNDA:0,::get_name +FNDA:0,conjure_core::solver::adaptors::minion::minion_rs_callback +FNDA:1,conjure_core::solver::adaptors::minion::_parse_intdomain_var +FNDA:0,conjure_core::solver::adaptors::minion::parse_vars +FNDA:1,conjure_core::solver::adaptors::minion::read_var +FNDA:0,::default +FNDA:0,conjure_core::solver::adaptors::minion::parse_vars +FNDA:0,::get_family +FNDA:0,conjure_core::solver::adaptors::minion::read_var +FNDA:1,conjure_core::solver::adaptors::minion::parse_var +FNDA:0,::solve::{closure#0}::{closure#0} +FNDA:1,conjure_core::solver::adaptors::minion::_parse_booldomain_var +FNDA:0,conjure_core::solver::adaptors::minion::minion_rs_callback::{closure#0}::{closure#0} +FNDA:0,conjure_core::solver::adaptors::minion::_name_to_string +FNDA:0,conjure_core::solver::adaptors::minion::minion_rs_callback::{closure#0} +FNDA:0,conjure_core::solver::adaptors::minion::read_expr::{closure#0} +FNDA:1,::solve::{closure#0} +FNDA:1,conjure_core::solver::adaptors::minion::parse_expr +FNDA:0,::solve::{closure#1} +FNDA:0,conjure_core::solver::adaptors::minion::read_const +FNDA:0,conjure_core::solver::adaptors::minion::_name_to_string +FNDA:0,conjure_core::solver::adaptors::minion::parse_var +FNDA:0,conjure_core::solver::adaptors::minion::_try_add_var +FNDA:0,conjure_core::solver::adaptors::minion::_try_add_var +FNDA:1,conjure_core::solver::adaptors::minion::parse_exprs +FNDA:0,conjure_core::solver::adaptors::minion::minion_rs_callback::{closure#0}::{closure#0} +FNDA:0,conjure_core::solver::adaptors::minion::_parse_intdomain_var +FNDA:0,conjure_core::solver::adaptors::minion::_read_ref +FNDA:0,conjure_core::solver::adaptors::minion::read_vars +FNDA:0,conjure_core::solver::adaptors::minion::read_const +FNDA:0,conjure_core::solver::adaptors::minion::read_expr::{closure#0} +FNDA:1,conjure_core::solver::adaptors::minion::read_vars +FNDA:0,::get_name +FNDA:0,conjure_core::solver::adaptors::minion::parse_var +FNDA:0,::new +FNDA:0,conjure_core::solver::adaptors::minion::_read_ref +FNDA:0,::solve_mut +FNDA:0,::solve::{closure#0}::{closure#0} +FNDA:1,conjure_core::solver::adaptors::minion::minion_rs_callback +FNDA:1,conjure_core::solver::adaptors::minion::read_expr +FNDA:0,conjure_core::solver::adaptors::minion::_parse_booldomain_var +FNDA:1,::get_family +FNDA:1,conjure_core::solver::adaptors::minion::parse_vars +FNDA:0,::default +FNDA:1,conjure_core::solver::adaptors::minion::read_const +FNDA:0,conjure_core::solver::adaptors::minion::read_expr +FNDA:0,conjure_core::solver::adaptors::minion::parse_exprs +FNDA:0,conjure_core::solver::adaptors::minion::read_var +FNDA:0,::solve +FNDA:0,::solve::{closure#1} +FNDA:0,conjure_core::solver::adaptors::minion::minion_rs_callback +FNDA:0,::load_model +FNDA:0,conjure_core::solver::adaptors::minion::minion_rs_callback::{closure#0}::{closure#0} +FNDA:0,::solve::{closure#1} +FNDA:0,::load_model +FNDA:0,::solve::{closure#0} +FNDA:0,conjure_core::solver::adaptors::minion::parse_expr +FNDA:0,conjure_core::solver::adaptors::minion::read_vars +FNDA:1,::load_model +FNDA:1,conjure_core::solver::adaptors::minion::read_expr::{closure#0} +FNDA:0,conjure_core::solver::adaptors::minion::_parse_booldomain_var +FNDA:0,conjure_core::solver::adaptors::minion::parse_expr +FNDA:0,::solve::{closure#0} +FNDA:0,conjure_core::solver::adaptors::minion::parse_exprs +FNDA:0,::solve_mut +FNDA:0,::get_family +FNDA:0,::default +FNDA:1,::solve +FNDA:1,conjure_core::solver::adaptors::minion::_try_add_var +FNDA:0,conjure_core::solver::adaptors::minion::minion_rs_callback::{closure#0} +FNDA:0,conjure_core::solver::adaptors::minion::_parse_intdomain_var +FNDA:1,::get_name +FNDA:0,::solve::{closure#0}::{closure#0} +FNF:81 +FNH:21 +BRF:0 +BRH:0 +DA:41,585 +DA:42,585 +DA:43,585 +DA:44,585 +DA:45,585 +DA:46,585 +DA:47,585 +DA:48,585 +DA:49,1575 +DA:50,1575 +DA:51,0 +DA:52,1575 +DA:53,0 +DA:56,1575 +DA:57,1575 +DA:58,375 +DA:60,1200 +DA:63,1575 +DA:66,585 +DA:67,585 +DA:68,0 +DA:69,585 +DA:71,585 +DA:72,585 +DA:77,180 +DA:78,180 +DA:79,180 +DA:80,180 +DA:81,180 +DA:82,180 +DA:86,0 +DA:87,0 +DA:88,0 +DA:93,180 +DA:94,180 +DA:95,180 +DA:96,180 +DA:97,180 +DA:98,180 +DA:99,180 +DA:100,180 +DA:101,180 +DA:102,180 +DA:103,180 +DA:104,180 +DA:105,180 +DA:106,180 +DA:107,180 +DA:108,180 +DA:109,180 +DA:110,180 +DA:111,180 +DA:112,180 +DA:113,180 +DA:114,180 +DA:115,180 +DA:116,180 +DA:117,0 +DA:118,0 +DA:119,0 +DA:120,0 +DA:121,180 +DA:123,180 +DA:124,180 +DA:125,0 +DA:126,180 +DA:127,180 +DA:128,180 +DA:129,180 +DA:130,180 +DA:131,180 +DA:132,180 +DA:133,180 +DA:135,0 +DA:136,0 +DA:137,0 +DA:138,0 +DA:139,0 +DA:140,0 +DA:141,0 +DA:143,180 +DA:144,180 +DA:145,180 +DA:146,180 +DA:147,180 +DA:148,180 +DA:149,180 +DA:151,180 +DA:152,180 +DA:153,180 +DA:155,180 +DA:156,180 +DA:157,180 +DA:160,180 +DA:161,180 +DA:162,180 +DA:163,180 +DA:167,465 +DA:168,465 +DA:170,180 +DA:171,180 +DA:173,465 +DA:174,465 +DA:175,465 +DA:176,465 +DA:177,465 +DA:178,465 +DA:179,360 +DA:180,105 +DA:181,0 +DA:183,465 +DA:185,360 +DA:186,360 +DA:187,360 +DA:188,360 +DA:189,360 +DA:190,360 +DA:191,360 +DA:192,360 +DA:193,0 +DA:194,0 +DA:195,0 +DA:196,0 +DA:197,0 +DA:198,360 +DA:200,360 +DA:201,360 +DA:202,360 +DA:203,360 +DA:205,360 +DA:206,360 +DA:207,0 +DA:209,0 +DA:210,0 +DA:212,360 +DA:213,360 +DA:214,360 +DA:215,360 +DA:216,360 +DA:217,360 +DA:219,105 +DA:220,105 +DA:221,105 +DA:222,105 +DA:223,105 +DA:224,105 +DA:225,105 +DA:226,105 +DA:227,105 +DA:228,105 +DA:229,105 +DA:231,465 +DA:232,465 +DA:233,465 +DA:234,465 +DA:235,465 +DA:236,465 +DA:237,465 +DA:238,465 +DA:239,465 +DA:240,465 +DA:241,465 +DA:242,465 +DA:243,465 +DA:245,180 +DA:246,180 +DA:247,180 +DA:248,180 +DA:249,675 +DA:250,675 +DA:252,180 +DA:253,180 +DA:255,675 +DA:256,675 +DA:257,675 +DA:258,675 +DA:259,675 +DA:260,675 +DA:261,675 +DA:263,1275 +DA:264,1275 +DA:265,45 +DA:266,45 +DA:267,45 +DA:269,30 +DA:270,30 +DA:271,30 +DA:273,870 +DA:274,870 +DA:275,870 +DA:276,870 +DA:278,0 +DA:279,0 +DA:280,0 +DA:289,30 +DA:290,30 +DA:292,300 +DA:293,300 +DA:294,300 +DA:295,600 +DA:296,300 +DA:298,0 +DA:300,1275 +DA:301,105 +DA:302,105 +DA:303,390 +DA:304,285 +DA:305,285 +DA:307,105 +DA:308,105 +DA:310,2100 +DA:311,2100 +DA:312,2100 +DA:313,1950 +DA:314,150 +DA:315,150 +DA:316,0 +DA:319,2100 +DA:321,2100 +DA:322,2100 +DA:323,1950 +DA:324,150 +DA:325,150 +DA:326,150 +DA:327,150 +DA:328,150 +DA:330,1950 +DA:331,1950 +DA:332,2100 +DA:334,1020 +DA:335,1020 +DA:336,1020 +DA:337,0 +DA:338,0 +DA:339,0 +DA:340,0 +DA:342,1020 +DA:344,2415 +DA:345,2415 +DA:346,1515 +DA:347,900 +DA:349,2415 +LF:242 +LH:206 +end_of_record +SF:crates/conjure_core/src/stats/solver_stats.rs +FN:33,::with_timings +FN:33,::with_timings +FN:33,::with_timings +FNDA:1,::with_timings +FNDA:0,::with_timings +FNDA:0,::with_timings +FNF:3 +FNH:1 +BRF:0 +BRH:0 +DA:33,180 +DA:34,180 +DA:35,180 +DA:36,180 +DA:37,180 +DA:38,180 +LF:6 +LH:6 +end_of_record +SF:crates/conjure_core/src/rule_engine/rule.rs +FN:71,::apply +FN:53,::with_symbols +FN:10,::fmt +FN:10,::fmt +FN:71,::apply +FN:125,::fmt +FN:35,::new +FN:53,::with_symbols +FN:44,::pure +FN:10,::fmt +FN:62,::with_top +FN:131,::eq +FN:107,::new +FN:119,::apply +FN:125,::fmt +FN:107,::new +FN:119,::apply +FN:139,::hash:: +FN:139,::hash::<_> +FN:35,::new +FN:35,::new +FN:119,::apply +FN:131,::eq +FN:62,::with_top +FN:71,::apply +FN:139,::hash:: +FN:125,::fmt +FN:131,::eq +FN:44,::pure +FN:44,::pure +FN:53,::with_symbols +FN:107,::new +FN:62,::with_top +FNDA:0,::apply +FNDA:0,::with_symbols +FNDA:0,::fmt +FNDA:0,::fmt +FNDA:0,::apply +FNDA:0,::fmt +FNDA:0,::new +FNDA:0,::with_symbols +FNDA:1,::pure +FNDA:0,::fmt +FNDA:0,::with_top +FNDA:0,::eq +FNDA:0,::new +FNDA:1,::apply +FNDA:0,::fmt +FNDA:0,::new +FNDA:0,::apply +FNDA:0,::hash:: +FNDA:0,::hash::<_> +FNDA:1,::new +FNDA:0,::new +FNDA:0,::apply +FNDA:0,::eq +FNDA:0,::with_top +FNDA:1,::apply +FNDA:1,::hash:: +FNDA:0,::fmt +FNDA:1,::eq +FNDA:0,::pure +FNDA:0,::pure +FNDA:0,::with_symbols +FNDA:0,::new +FNDA:0,::with_top +FNF:33 +FNH:6 +BRF:0 +BRH:0 +DA:10,0 +DA:35,1845 +DA:36,1845 +DA:37,1845 +DA:38,1845 +DA:39,1845 +DA:40,1845 +DA:41,1845 +DA:44,1815 +DA:45,1815 +DA:46,1815 +DA:47,1815 +DA:48,1815 +DA:49,1815 +DA:50,1815 +DA:53,0 +DA:54,0 +DA:55,0 +DA:56,0 +DA:57,0 +DA:58,0 +DA:59,0 +DA:62,0 +DA:63,0 +DA:64,0 +DA:65,0 +DA:66,0 +DA:67,0 +DA:68,0 +DA:71,1590 +DA:72,1590 +DA:73,1590 +DA:74,1515 +DA:75,1515 +DA:76,75 +DA:77,0 +DA:78,0 +DA:79,0 +DA:80,0 +DA:82,75 +DA:83,75 +DA:84,75 +DA:85,75 +DA:88,1590 +DA:107,0 +DA:108,0 +DA:109,0 +DA:110,0 +DA:111,0 +DA:112,0 +DA:113,0 +DA:114,0 +DA:115,0 +DA:116,0 +DA:117,0 +DA:119,770670 +DA:120,770670 +DA:121,770670 +DA:125,0 +DA:126,0 +DA:127,0 +DA:131,39330 +DA:132,39330 +DA:133,39330 +DA:139,62280 +DA:140,62280 +DA:141,62280 +LF:67 +LH:34 +end_of_record +SF:solvers/minion/src/ast.rs +FN:28,::default +FN:19,::new +FN:28,::default +FN:19,::new +FN:161,::new +FN:198,::contains +FN:173,::add_var +FN:189,::get_vartype +FN:194,::get_variable_order +FN:173,::add_var +FN:19,::new +FN:173,::add_var +FN:194,::get_variable_order +FN:161,::new +FN:189,::get_vartype +FN:198,::contains +FN:28,::default +FN:161,::new +FN:189,::get_vartype +FN:194,::get_variable_order +FN:198,::contains +FNDA:0,::default +FNDA:0,::new +FNDA:0,::default +FNDA:0,::new +FNDA:1,::new +FNDA:0,::contains +FNDA:0,::add_var +FNDA:1,::get_vartype +FNDA:0,::get_variable_order +FNDA:0,::add_var +FNDA:1,::new +FNDA:1,::add_var +FNDA:0,::get_variable_order +FNDA:0,::new +FNDA:0,::get_vartype +FNDA:0,::contains +FNDA:0,::default +FNDA:0,::new +FNDA:0,::get_vartype +FNDA:1,::get_variable_order +FNDA:0,::contains +FNF:21 +FNH:5 +BRF:0 +BRH:0 +DA:19,285 +DA:20,285 +DA:21,285 +DA:22,285 +DA:23,285 +DA:24,285 +DA:28,0 +DA:29,0 +DA:30,0 +DA:161,285 +DA:162,285 +DA:163,285 +DA:164,285 +DA:165,285 +DA:166,285 +DA:173,760 +DA:174,760 +DA:175,0 +DA:176,760 +DA:177,760 +DA:178,760 +DA:179,760 +DA:180,760 +DA:181,760 +DA:182,760 +DA:189,760 +DA:190,760 +DA:191,760 +DA:194,285 +DA:195,285 +DA:196,285 +DA:198,0 +DA:199,0 +DA:200,0 +LF:34 +LH:27 +end_of_record +SF:crates/enum_compatability_macro/src/lib.rs +FN:131,enum_compatability_macro::document_compatibility +FN:131,enum_compatability_macro::document_compatibility +FN:131,enum_compatability_macro::document_compatibility +FN:131,enum_compatability_macro::document_compatibility +FN:118,rust_out::main +FN:38,::visit_variant_mut +FN:38,::visit_variant_mut +FN:38,::visit_variant_mut +FN:66,::visit_variant_mut::{closure#0} +FN:66,::visit_variant_mut::{closure#0} +FN:181,enum_compatability_macro::document_compatibility::{closure#0} +FN:66,::visit_variant_mut::{closure#0} +FN:66,::visit_variant_mut::{closure#0} +FN:118,rust_out::main::_doctest_main_crates_enum_compatability_macro_src_lib_rs_117_0 +FN:38,::visit_variant_mut +FN:75,rust_out::main::_doctest_main_crates_enum_compatability_macro_src_lib_rs_74_0 +FN:181,enum_compatability_macro::document_compatibility::{closure#0} +FN:104,rust_out::main::_doctest_main_crates_enum_compatability_macro_src_lib_rs_103_0 +FN:181,enum_compatability_macro::document_compatibility::{closure#0} +FN:181,enum_compatability_macro::document_compatibility::{closure#0} +FNDA:1,enum_compatability_macro::document_compatibility +FNDA:0,enum_compatability_macro::document_compatibility +FNDA:0,enum_compatability_macro::document_compatibility +FNDA:1,enum_compatability_macro::document_compatibility +FNDA:1,rust_out::main +FNDA:0,::visit_variant_mut +FNDA:1,::visit_variant_mut +FNDA:0,::visit_variant_mut +FNDA:1,::visit_variant_mut::{closure#0} +FNDA:0,::visit_variant_mut::{closure#0} +FNDA:1,enum_compatability_macro::document_compatibility::{closure#0} +FNDA:0,::visit_variant_mut::{closure#0} +FNDA:1,::visit_variant_mut::{closure#0} +FNDA:1,rust_out::main::_doctest_main_crates_enum_compatability_macro_src_lib_rs_117_0 +FNDA:1,::visit_variant_mut +FNDA:1,rust_out::main::_doctest_main_crates_enum_compatability_macro_src_lib_rs_74_0 +FNDA:0,enum_compatability_macro::document_compatibility::{closure#0} +FNDA:1,rust_out::main::_doctest_main_crates_enum_compatability_macro_src_lib_rs_103_0 +FNDA:1,enum_compatability_macro::document_compatibility::{closure#0} +FNDA:0,enum_compatability_macro::document_compatibility::{closure#0} +FNF:20 +FNH:12 +BRF:0 +BRH:0 +DA:38,120 +DA:39,120 +DA:40,120 +DA:41,120 +DA:42,120 +DA:43,120 +DA:44,120 +DA:45,120 +DA:46,116 +DA:47,6 +DA:48,110 +DA:49,110 +DA:50,110 +DA:51,110 +DA:52,263 +DA:53,153 +DA:54,153 +DA:55,153 +DA:56,153 +DA:59,120 +DA:60,108 +DA:61,108 +DA:62,108 +DA:63,108 +DA:64,108 +DA:66,224 +DA:67,120 +DA:75,1 +DA:76,1 +DA:77,1 +DA:78,1 +DA:79,1 +DA:80,1 +DA:81,1 +DA:82,1 +DA:83,1 +DA:84,1 +DA:85,1 +DA:86,1 +DA:87,1 +DA:104,1 +DA:105,1 +DA:106,1 +DA:107,1 +DA:108,1 +DA:109,1 +DA:110,1 +DA:111,1 +DA:112,1 +DA:113,1 +DA:114,1 +DA:115,1 +DA:116,1 +DA:118,1 +DA:119,1 +DA:120,1 +DA:121,1 +DA:122,1 +DA:123,1 +DA:124,1 +DA:125,1 +DA:126,1 +DA:127,1 +DA:128,1 +DA:129,1 +DA:131,9 +DA:133,9 +DA:134,9 +DA:137,120 +DA:138,120 +DA:139,120 +DA:140,116 +DA:141,6 +DA:142,110 +DA:143,110 +DA:144,110 +DA:145,110 +DA:146,110 +DA:147,263 +DA:148,153 +DA:149,153 +DA:150,153 +DA:151,24 +DA:152,24 +DA:153,24 +DA:154,129 +DA:155,129 +DA:156,129 +DA:164,9 +DA:165,9 +DA:166,9 +DA:167,9 +DA:168,9 +DA:169,9 +DA:170,9 +DA:171,9 +DA:172,24 +DA:174,24 +DA:177,153 +DA:178,24 +DA:179,24 +DA:180,24 +DA:181,153 +DA:182,24 +DA:183,153 +DA:184,153 +DA:185,153 +DA:188,24 +DA:191,9 +DA:192,9 +DA:193,9 +DA:194,9 +DA:195,9 +DA:196,9 +DA:197,9 +LF:115 +LH:115 +end_of_record +SF:crates/uniplate/src/tree.rs +FN:26, as core::iter::traits::collect::IntoIterator>::into_iter +FN:77,>::list::{closure#0} +FN:47,>::list::flatten::::{closure#0} +FN:65,>::list::recons::::{closure#0} +FN:133,uniplate::tree::tests::list_preserves_ordering +FN:86,>::map::{closure#0} +FN:53,>::list::recons:: +FN:77,>::list::{closure#0} +FN:93,uniplate::tree::proptest_integer_trees +FN:39,>::list::flatten:: +FN:123,uniplate::tree::tests::map_add::{closure#1}::{closure#0} +FN:102,uniplate::tree::proptest_integer_trees::{closure#0} +FN:65,>::list::recons::::{closure#0} +FN:53,>::list::recons:: +FN:82,>::map +FN:35,>::list +FN:35,>::list +FN:39,>::list::flatten:: +FN:47,>::list::flatten::::{closure#0} +FNDA:0, as core::iter::traits::collect::IntoIterator>::into_iter +FNDA:0,>::list::{closure#0} +FNDA:1,>::list::flatten::::{closure#0} +FNDA:1,>::list::recons::::{closure#0} +FNDA:1,uniplate::tree::tests::list_preserves_ordering +FNDA:1,>::map::{closure#0} +FNDA:1,>::list::recons:: +FNDA:1,>::list::{closure#0} +FNDA:1,uniplate::tree::proptest_integer_trees +FNDA:1,>::list::flatten:: +FNDA:1,uniplate::tree::tests::map_add::{closure#1}::{closure#0} +FNDA:1,uniplate::tree::proptest_integer_trees::{closure#0} +FNDA:0,>::list::recons::::{closure#0} +FNDA:0,>::list::recons:: +FNDA:1,>::map +FNDA:1,>::list +FNDA:1,>::list +FNDA:1,>::list::flatten:: +FNDA:1,>::list::flatten::::{closure#0} +FNF:19 +FNH:15 +BRF:0 +BRH:0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:35,785 +DA:36,785 +DA:37,785 +DA:38,785 +DA:39,28415 +DA:40,28415 +DA:41,12883 +DA:42,12581 +DA:43,12581 +DA:44,12581 +DA:45,12581 +DA:46,785 +DA:47,27630 +DA:48,785 +DA:49,28415 +DA:50,785 +DA:51,785 +DA:52,785 +DA:53,10033 +DA:54,10023 +DA:55,10023 +DA:56,10023 +DA:57,10023 +DA:58,10023 +DA:59,4586 +DA:60,4436 +DA:61,4426 +DA:62,4426 +DA:63,785 +DA:64,1031 +DA:65,9765 +DA:66,9765 +DA:67,9765 +DA:68,9765 +DA:69,9765 +DA:70,9765 +DA:71,1021 +DA:72,785 +DA:73,785 +DA:74,10033 +DA:75,785 +DA:76,785 +DA:77,785 +DA:78,785 +DA:79,785 +DA:82,9170 +DA:83,9170 +DA:84,4147 +DA:85,4069 +DA:86,8912 +DA:88,9170 +DA:93,2 +DA:94,2 +DA:95,2 +DA:96,2 +DA:97,2 +DA:98,2 +DA:99,2 +DA:100,2 +DA:101,2 +DA:102,5160 +DA:103,2 +DA:104,2 +DA:123,4069 +DA:133,1 +DA:134,1 +DA:135,1 +DA:136,1 +DA:137,1 +DA:138,1 +DA:139,1 +DA:140,1 +DA:141,1 +DA:142,1 +DA:144,6 +DA:145,5 +DA:147,1 +LF:80 +LH:77 +end_of_record +SF:crates/conjure_core/src/rule_engine/rewrite.rs +FN:64,conjure_core::rule_engine::rewrite::rewrite_iteration +FN:90,conjure_core::rule_engine::rewrite::apply_all_rules +FN:28,::fmt +FN:64,conjure_core::rule_engine::rewrite::rewrite_iteration +FN:90,conjure_core::rule_engine::rewrite::apply_all_rules +FN:28,::fmt +FN:36,>::from +FN:117,conjure_core::rule_engine::rewrite::choose_rewrite +FN:117,conjure_core::rule_engine::rewrite::choose_rewrite +FN:64,conjure_core::rule_engine::rewrite::rewrite_iteration +FN:36,>::from +FN:36,>::from +FN:117,conjure_core::rule_engine::rewrite::choose_rewrite +FN:47,conjure_core::rule_engine::rewrite::rewrite_model +FN:47,conjure_core::rule_engine::rewrite::rewrite_model +FN:47,conjure_core::rule_engine::rewrite::rewrite_model +FN:28,::fmt +FN:90,conjure_core::rule_engine::rewrite::apply_all_rules +FNDA:0,conjure_core::rule_engine::rewrite::rewrite_iteration +FNDA:1,conjure_core::rule_engine::rewrite::apply_all_rules +FNDA:0,::fmt +FNDA:1,conjure_core::rule_engine::rewrite::rewrite_iteration +FNDA:0,conjure_core::rule_engine::rewrite::apply_all_rules +FNDA:0,::fmt +FNDA:0,>::from +FNDA:0,conjure_core::rule_engine::rewrite::choose_rewrite +FNDA:1,conjure_core::rule_engine::rewrite::choose_rewrite +FNDA:0,conjure_core::rule_engine::rewrite::rewrite_iteration +FNDA:0,>::from +FNDA:0,>::from +FNDA:0,conjure_core::rule_engine::rewrite::choose_rewrite +FNDA:1,conjure_core::rule_engine::rewrite::rewrite_model +FNDA:0,conjure_core::rule_engine::rewrite::rewrite_model +FNDA:0,conjure_core::rule_engine::rewrite::rewrite_model +FNDA:0,::fmt +FNDA:0,conjure_core::rule_engine::rewrite::apply_all_rules +FNF:18 +FNH:4 +BRF:0 +BRH:0 +DA:28,0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:36,0 +DA:37,0 +DA:38,0 +DA:47,165 +DA:48,165 +DA:49,165 +DA:50,165 +DA:51,165 +DA:52,165 +DA:53,165 +DA:55,1755 +DA:56,1590 +DA:57,1590 +DA:58,165 +DA:59,165 +DA:64,29385 +DA:65,29385 +DA:66,29385 +DA:67,29385 +DA:68,29385 +DA:69,29385 +DA:70,29385 +DA:71,1590 +DA:73,27795 +DA:75,27795 +DA:76,27630 +DA:77,1770 +DA:78,1770 +DA:79,1770 +DA:80,0 +DA:81,25860 +DA:84,26025 +DA:85,29385 +DA:90,29385 +DA:91,29385 +DA:92,29385 +DA:93,29385 +DA:94,29385 +DA:95,29385 +DA:96,793395 +DA:97,764010 +DA:98,1620 +DA:99,1620 +DA:100,1620 +DA:101,1620 +DA:102,1620 +DA:103,1620 +DA:106,762390 +DA:107,762390 +DA:111,29385 +DA:112,29385 +DA:117,29385 +DA:118,29385 +DA:119,27795 +DA:120,1590 +DA:121,1590 +DA:122,1590 +DA:123,29385 +LF:63 +LH:54 +end_of_record +SF:crates/conjure_core/src/rules/constant.rs +FN:33,conjure_core::rules::constant::eval_constant::{closure#4} +FN:49,conjure_core::rules::constant::eval_constant::{closure#11} +FN:10,conjure_core::rules::constant::CONJURE_GEN_RULE_APPLY_EVAL_CONSTANT::__typecheck::{closure#0}::{closure#0} +FN:87,conjure_core::rules::constant::tern_op:: +FN:53,conjure_core::rules::constant::eval_constant::{closure#12} +FN:43,conjure_core::rules::constant::eval_constant::{closure#9}::{closure#0} +FN:56,conjure_core::rules::constant::eval_constant::{closure#13} +FN:10,conjure_core::rules::constant::CONJURE_GEN_RULE_APPLY_EVAL_CONSTANT::__typecheck +FN:78,conjure_core::rules::constant::bin_op:: +FN:8,conjure_core::rules::constant::CONJURE_GEN_RULE_SET_CONSTANT::__typecheck +FN:78,conjure_core::rules::constant::bin_op:: +FN:43,conjure_core::rules::constant::eval_constant::{closure#9} +FN:10,conjure_core::rules::constant::CONJURE_GEN_RULE_APPLY_EVAL_CONSTANT::__typecheck::{closure#0} +FN:43,conjure_core::rules::constant::eval_constant::{closure#9}::{closure#0} +FN:49,conjure_core::rules::constant::eval_constant::{closure#11} +FN:97,conjure_core::rules::constant::vec_op:: +FN:40,conjure_core::rules::constant::eval_constant::{closure#8} +FN:40,conjure_core::rules::constant::eval_constant::{closure#8}::{closure#0} +FN:122,conjure_core::rules::constant::unwrap_expr:: +FN:78,conjure_core::rules::constant::bin_op:: +FN:56,conjure_core::rules::constant::eval_constant::{closure#13} +FN:34,conjure_core::rules::constant::eval_constant::{closure#5} +FN:8,conjure_core::rules::constant::CONJURE_GEN_RULE_SET_CONSTANT::__typecheck +FN:10,conjure_core::rules::constant::CONJURE_GEN_RULE_APPLY_EVAL_CONSTANT::__typecheck +FN:35,conjure_core::rules::constant::eval_constant::{closure#6} +FN:97,conjure_core::rules::constant::vec_op:: +FN:34,conjure_core::rules::constant::eval_constant::{closure#5} +FN:16,conjure_core::rules::constant::apply_eval_constant::{closure#0} +FN:29,conjure_core::rules::constant::eval_constant::{closure#1}::{closure#0} +FN:29,conjure_core::rules::constant::eval_constant::{closure#1} +FN:105,conjure_core::rules::constant::opt_vec_op:: +FN:10,conjure_core::rules::constant::CONJURE_GEN_RULE_APPLY_EVAL_CONSTANT::__typecheck +FN:35,conjure_core::rules::constant::eval_constant::{closure#6} +FN:8,conjure_core::rules::constant::CONJURE_GEN_RULE_SET_CONSTANT::__typecheck::{closure#0} +FN:32,conjure_core::rules::constant::eval_constant::{closure#3} +FN:46,conjure_core::rules::constant::eval_constant::{closure#10} +FN:28,conjure_core::rules::constant::eval_constant::{closure#0} +FN:53,conjure_core::rules::constant::eval_constant::{closure#12} +FN:78,conjure_core::rules::constant::bin_op:: +FN:31,conjure_core::rules::constant::eval_constant::{closure#2} +FN:40,conjure_core::rules::constant::eval_constant::{closure#8} +FN:49,conjure_core::rules::constant::eval_constant::{closure#11} +FN:10,conjure_core::rules::constant::CONJURE_GEN_RULE_APPLY_EVAL_CONSTANT::__typecheck::{closure#0}::{closure#0} +FN:113,conjure_core::rules::constant::flat_op:: +FN:87,conjure_core::rules::constant::tern_op:: +FN:122,conjure_core::rules::constant::unwrap_expr:: +FN:10,conjure_core::rules::constant::CONJURE_GEN_RULE_APPLY_EVAL_CONSTANT::__typecheck::{closure#0} +FN:43,conjure_core::rules::constant::eval_constant::{closure#9} +FN:11,conjure_core::rules::constant::apply_eval_constant +FN:31,conjure_core::rules::constant::eval_constant::{closure#2} +FN:122,conjure_core::rules::constant::unwrap_expr:: +FN:40,conjure_core::rules::constant::eval_constant::{closure#8}::{closure#0} +FN:29,conjure_core::rules::constant::eval_constant::{closure#1}::{closure#0} +FN:46,conjure_core::rules::constant::eval_constant::{closure#10} +FN:87,conjure_core::rules::constant::tern_op:: +FN:8,conjure_core::rules::constant::CONJURE_GEN_RULE_SET_CONSTANT::__typecheck::{closure#0} +FN:16,conjure_core::rules::constant::apply_eval_constant::{closure#0} +FN:8,conjure_core::rules::constant::CONJURE_GEN_RULE_SET_CONSTANT::__typecheck::{closure#0}::{closure#0} +FN:8,conjure_core::rules::constant::CONJURE_GEN_RULE_SET_CONSTANT::__typecheck::{closure#0}::{closure#0} +FN:97,conjure_core::rules::constant::vec_op:: +FN:53,conjure_core::rules::constant::eval_constant::{closure#12} +FN:33,conjure_core::rules::constant::eval_constant::{closure#4} +FN:105,conjure_core::rules::constant::opt_vec_op:: +FN:28,conjure_core::rules::constant::eval_constant::{closure#0} +FN:61,conjure_core::rules::constant::eval_constant::{closure#14} +FN:61,conjure_core::rules::constant::eval_constant::{closure#14} +FN:32,conjure_core::rules::constant::eval_constant::{closure#3} +FN:10,conjure_core::rules::constant::CONJURE_GEN_RULE_APPLY_EVAL_CONSTANT::__typecheck::{closure#0}::{closure#0} +FN:37,conjure_core::rules::constant::eval_constant::{closure#7} +FN:37,conjure_core::rules::constant::eval_constant::{closure#7} +FN:11,conjure_core::rules::constant::apply_eval_constant +FN:97,conjure_core::rules::constant::vec_op:: +FN:78,conjure_core::rules::constant::bin_op:: +FN:40,conjure_core::rules::constant::eval_constant::{closure#8} +FN:70,conjure_core::rules::constant::un_op:: +FN:56,conjure_core::rules::constant::eval_constant::{closure#13} +FN:24,conjure_core::rules::constant::eval_constant +FN:8,conjure_core::rules::constant::CONJURE_GEN_RULE_SET_CONSTANT::__typecheck::{closure#0}::{closure#0} +FN:34,conjure_core::rules::constant::eval_constant::{closure#5} +FN:16,conjure_core::rules::constant::apply_eval_constant::{closure#0} +FN:43,conjure_core::rules::constant::eval_constant::{closure#9} +FN:40,conjure_core::rules::constant::eval_constant::{closure#8}::{closure#0} +FN:33,conjure_core::rules::constant::eval_constant::{closure#4} +FN:70,conjure_core::rules::constant::un_op:: +FN:122,conjure_core::rules::constant::unwrap_expr:: +FN:122,conjure_core::rules::constant::unwrap_expr:: +FN:28,conjure_core::rules::constant::eval_constant::{closure#0} +FN:78,conjure_core::rules::constant::bin_op:: +FN:8,conjure_core::rules::constant::CONJURE_GEN_RULE_SET_CONSTANT::__typecheck +FN:8,conjure_core::rules::constant::CONJURE_GEN_RULE_SET_CONSTANT::__typecheck::{closure#0} +FN:97,conjure_core::rules::constant::vec_op:: +FN:10,conjure_core::rules::constant::CONJURE_GEN_RULE_APPLY_EVAL_CONSTANT::__typecheck::{closure#0} +FN:43,conjure_core::rules::constant::eval_constant::{closure#9}::{closure#0} +FN:70,conjure_core::rules::constant::un_op:: +FN:113,conjure_core::rules::constant::flat_op:: +FN:35,conjure_core::rules::constant::eval_constant::{closure#6} +FN:29,conjure_core::rules::constant::eval_constant::{closure#1} +FN:113,conjure_core::rules::constant::flat_op:: +FN:46,conjure_core::rules::constant::eval_constant::{closure#10} +FN:29,conjure_core::rules::constant::eval_constant::{closure#1}::{closure#0} +FN:31,conjure_core::rules::constant::eval_constant::{closure#2} +FN:29,conjure_core::rules::constant::eval_constant::{closure#1} +FN:105,conjure_core::rules::constant::opt_vec_op:: +FN:97,conjure_core::rules::constant::vec_op:: +FN:61,conjure_core::rules::constant::eval_constant::{closure#14} +FN:24,conjure_core::rules::constant::eval_constant +FN:122,conjure_core::rules::constant::unwrap_expr:: +FN:24,conjure_core::rules::constant::eval_constant +FN:11,conjure_core::rules::constant::apply_eval_constant +FN:37,conjure_core::rules::constant::eval_constant::{closure#7} +FN:32,conjure_core::rules::constant::eval_constant::{closure#3} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#4} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#11} +FNDA:0,conjure_core::rules::constant::CONJURE_GEN_RULE_APPLY_EVAL_CONSTANT::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::constant::tern_op:: +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#12} +FNDA:1,conjure_core::rules::constant::eval_constant::{closure#9}::{closure#0} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#13} +FNDA:0,conjure_core::rules::constant::CONJURE_GEN_RULE_APPLY_EVAL_CONSTANT::__typecheck +FNDA:0,conjure_core::rules::constant::bin_op:: +FNDA:0,conjure_core::rules::constant::CONJURE_GEN_RULE_SET_CONSTANT::__typecheck +FNDA:0,conjure_core::rules::constant::bin_op:: +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#9} +FNDA:0,conjure_core::rules::constant::CONJURE_GEN_RULE_APPLY_EVAL_CONSTANT::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#9}::{closure#0} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#11} +FNDA:0,conjure_core::rules::constant::vec_op:: +FNDA:1,conjure_core::rules::constant::eval_constant::{closure#8} +FNDA:1,conjure_core::rules::constant::eval_constant::{closure#8}::{closure#0} +FNDA:0,conjure_core::rules::constant::unwrap_expr:: +FNDA:1,conjure_core::rules::constant::bin_op:: +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#13} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#5} +FNDA:0,conjure_core::rules::constant::CONJURE_GEN_RULE_SET_CONSTANT::__typecheck +FNDA:0,conjure_core::rules::constant::CONJURE_GEN_RULE_APPLY_EVAL_CONSTANT::__typecheck +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#6} +FNDA:0,conjure_core::rules::constant::vec_op:: +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#5} +FNDA:0,conjure_core::rules::constant::apply_eval_constant::{closure#0} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#1}::{closure#0} +FNDA:1,conjure_core::rules::constant::eval_constant::{closure#1} +FNDA:0,conjure_core::rules::constant::opt_vec_op:: +FNDA:0,conjure_core::rules::constant::CONJURE_GEN_RULE_APPLY_EVAL_CONSTANT::__typecheck +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#6} +FNDA:0,conjure_core::rules::constant::CONJURE_GEN_RULE_SET_CONSTANT::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#3} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#10} +FNDA:1,conjure_core::rules::constant::eval_constant::{closure#0} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#12} +FNDA:1,conjure_core::rules::constant::bin_op:: +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#2} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#8} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#11} +FNDA:0,conjure_core::rules::constant::CONJURE_GEN_RULE_APPLY_EVAL_CONSTANT::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::constant::flat_op:: +FNDA:0,conjure_core::rules::constant::tern_op:: +FNDA:0,conjure_core::rules::constant::unwrap_expr:: +FNDA:0,conjure_core::rules::constant::CONJURE_GEN_RULE_APPLY_EVAL_CONSTANT::__typecheck::{closure#0} +FNDA:1,conjure_core::rules::constant::eval_constant::{closure#9} +FNDA:0,conjure_core::rules::constant::apply_eval_constant +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#2} +FNDA:1,conjure_core::rules::constant::unwrap_expr:: +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#8}::{closure#0} +FNDA:1,conjure_core::rules::constant::eval_constant::{closure#1}::{closure#0} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#10} +FNDA:1,conjure_core::rules::constant::tern_op:: +FNDA:0,conjure_core::rules::constant::CONJURE_GEN_RULE_SET_CONSTANT::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::constant::apply_eval_constant::{closure#0} +FNDA:0,conjure_core::rules::constant::CONJURE_GEN_RULE_SET_CONSTANT::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::constant::CONJURE_GEN_RULE_SET_CONSTANT::__typecheck::{closure#0}::{closure#0} +FNDA:1,conjure_core::rules::constant::vec_op:: +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#12} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#4} +FNDA:1,conjure_core::rules::constant::opt_vec_op:: +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#0} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#14} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#14} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#3} +FNDA:0,conjure_core::rules::constant::CONJURE_GEN_RULE_APPLY_EVAL_CONSTANT::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#7} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#7} +FNDA:0,conjure_core::rules::constant::apply_eval_constant +FNDA:0,conjure_core::rules::constant::vec_op:: +FNDA:0,conjure_core::rules::constant::bin_op:: +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#8} +FNDA:0,conjure_core::rules::constant::un_op:: +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#13} +FNDA:0,conjure_core::rules::constant::eval_constant +FNDA:0,conjure_core::rules::constant::CONJURE_GEN_RULE_SET_CONSTANT::__typecheck::{closure#0}::{closure#0} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#5} +FNDA:0,conjure_core::rules::constant::apply_eval_constant::{closure#0} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#9} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#8}::{closure#0} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#4} +FNDA:0,conjure_core::rules::constant::un_op:: +FNDA:1,conjure_core::rules::constant::unwrap_expr:: +FNDA:0,conjure_core::rules::constant::unwrap_expr:: +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#0} +FNDA:0,conjure_core::rules::constant::bin_op:: +FNDA:0,conjure_core::rules::constant::CONJURE_GEN_RULE_SET_CONSTANT::__typecheck +FNDA:0,conjure_core::rules::constant::CONJURE_GEN_RULE_SET_CONSTANT::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::constant::vec_op:: +FNDA:0,conjure_core::rules::constant::CONJURE_GEN_RULE_APPLY_EVAL_CONSTANT::__typecheck::{closure#0} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#9}::{closure#0} +FNDA:0,conjure_core::rules::constant::un_op:: +FNDA:1,conjure_core::rules::constant::flat_op:: +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#6} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#1} +FNDA:0,conjure_core::rules::constant::flat_op:: +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#10} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#1}::{closure#0} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#2} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#1} +FNDA:0,conjure_core::rules::constant::opt_vec_op:: +FNDA:1,conjure_core::rules::constant::vec_op:: +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#14} +FNDA:0,conjure_core::rules::constant::eval_constant +FNDA:0,conjure_core::rules::constant::unwrap_expr:: +FNDA:1,conjure_core::rules::constant::eval_constant +FNDA:1,conjure_core::rules::constant::apply_eval_constant +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#7} +FNDA:0,conjure_core::rules::constant::eval_constant::{closure#3} +FNF:111 +FNH:18 +BRF:0 +BRH:0 +DA:8,0 +DA:10,0 +DA:11,29610 +DA:12,29610 +DA:13,7200 +DA:14,22410 +DA:15,22410 +DA:16,22410 +DA:17,22410 +DA:18,29610 +DA:24,39255 +DA:25,39255 +DA:26,1260 +DA:27,22440 +DA:28,150 +DA:29,150 +DA:30,150 +DA:31,30 +DA:32,15 +DA:33,0 +DA:34,870 +DA:35,495 +DA:37,0 +DA:39,1830 +DA:40,1830 +DA:42,2190 +DA:43,2190 +DA:46,330 +DA:48,9045 +DA:49,9045 +DA:52,180 +DA:53,180 +DA:55,75 +DA:56,75 +DA:60,225 +DA:61,225 +DA:64,120 +DA:65,120 +DA:68,39255 +DA:70,0 +DA:71,0 +DA:72,0 +DA:73,0 +DA:74,0 +DA:75,0 +DA:76,0 +DA:78,1695 +DA:79,1695 +DA:80,1695 +DA:81,1695 +DA:82,1695 +DA:83,45 +DA:84,30 +DA:85,1695 +DA:87,9045 +DA:88,9045 +DA:89,9045 +DA:90,9045 +DA:91,9045 +DA:92,990 +DA:93,0 +DA:94,0 +DA:95,9045 +DA:97,4350 +DA:98,4350 +DA:99,4350 +DA:100,4350 +DA:101,4350 +DA:102,30 +DA:103,4350 +DA:105,225 +DA:106,225 +DA:107,225 +DA:108,225 +DA:109,225 +DA:110,0 +DA:111,225 +DA:113,255 +DA:114,255 +DA:115,255 +DA:116,255 +DA:117,255 +DA:118,0 +DA:119,0 +DA:120,255 +DA:122,16680 +DA:123,16680 +DA:124,1230 +DA:125,16680 +LF:89 +LH:73 +end_of_record +SF:crates/conjure_core/src/ast/domains.rs +FN:3,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:57,::min_max_i32 +FN:57,::min_max_i32 +FN:9,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FN:9,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FN:9,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:3,< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::expecting +FN:9,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:3,<< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::__Visitor<_> as serde::de::Visitor>::visit_seq::<_> +FN:3,< as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FN:3,< as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FN:3,< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::<_> +FN:3,<< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::__Visitor<_> as serde::de::Visitor>::visit_seq::<_> +FN:3,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:3,< as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FN:3,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:3,< as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FN:9,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:3,< as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FN:9,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:9,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FN:3,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:9,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FN:37,::max_i32 +FN:3,< as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:3,< as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:9,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FN:3,<< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:3,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:3,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:3,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:3,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:3,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:9,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FN:9,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:3,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:9,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:9,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:3,< as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FN:9,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:17,::min_i32 +FN:9,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:9,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:9,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FN:9,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:3,<< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FN:3,<< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::__Visitor<_> as serde::de::Visitor>::expecting +FN:3,<< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FN:3,<< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::__Visitor<_> as serde::de::Visitor>::expecting +FN:3,< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::expecting +FN:3,<< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::__Visitor<_> as serde::de::Visitor>::visit_seq::<_> +FN:17,::min_i32 +FN:9,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FN:57,::min_max_i32 +FN:3,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:9,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:3,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FN:17,::min_i32 +FN:3,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:9,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:37,::max_i32 +FN:9,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:3,< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::<_> +FN:3,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FN:9,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:3,< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::<_> +FN:9,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FN:3,< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::expecting +FN:9,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:37,::max_i32 +FN:3,<< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::__Visitor<_> as serde::de::Visitor>::expecting +FN:9,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:9,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FN:9,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FN:3,< as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:9,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:3,<< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,::min_max_i32 +FNDA:1,::min_max_i32 +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FNDA:1,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,<< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::__Visitor<_> as serde::de::Visitor>::visit_seq::<_> +FNDA:0,< as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FNDA:0,< as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FNDA:0,< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::<_> +FNDA:0,<< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::__Visitor<_> as serde::de::Visitor>::visit_seq::<_> +FNDA:0,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:1,< as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FNDA:0,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,< as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,< as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FNDA:0,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FNDA:0,::max_i32 +FNDA:0,< as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,< as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:1,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FNDA:0,<< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:1,< as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,::min_i32 +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:1,<< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNDA:0,<< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::__Visitor<_> as serde::de::Visitor>::expecting +FNDA:0,<< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::__Visitor<_> as serde::de::Visitor>::expecting +FNDA:0,< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::expecting +FNDA:0,<< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::__Visitor<_> as serde::de::Visitor>::visit_seq::<_> +FNDA:0,::min_i32 +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FNDA:0,::min_max_i32 +FNDA:0,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FNDA:0,::min_i32 +FNDA:0,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,::max_i32 +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::<_> +FNDA:1,< as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:0,< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FNDA:0,< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,::max_i32 +FNDA:0,<< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::__Visitor<_> as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:1,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FNDA:1,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FNDA:0,< as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,<< as serde::de::Deserialize>::deserialize::__Visitor<_> as serde::de::Visitor>::visit_enum::__Visitor as serde::de::Visitor>::visit_seq::> +FNF:77 +FNH:9 +BRF:0 +BRH:0 +DA:3,465 +DA:9,410 +DA:17,0 +DA:18,0 +DA:19,0 +DA:20,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:24,0 +DA:25,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:31,0 +DA:34,0 +DA:37,0 +DA:38,0 +DA:39,0 +DA:40,0 +DA:41,0 +DA:42,0 +DA:43,0 +DA:44,0 +DA:45,0 +DA:46,0 +DA:47,0 +DA:48,0 +DA:51,0 +DA:54,0 +DA:57,150 +DA:58,150 +DA:59,0 +DA:60,150 +DA:61,150 +DA:62,0 +DA:63,150 +DA:64,150 +DA:65,150 +DA:66,300 +DA:67,150 +DA:68,0 +DA:69,0 +DA:70,0 +DA:71,0 +DA:72,150 +DA:73,150 +DA:74,150 +DA:75,150 +DA:78,150 +DA:81,150 +LF:51 +LH:17 +end_of_record +SF:crates/conjure_core/src/context.rs +FN:54,::new_ptr +FN:74,::fmt::{closure#1} +FN:14,::eq +FN:70,::fmt +FN:14,::eq +FN:36,::new +FN:36,::new +FN:73,::fmt::{closure#0} +FN:73,::fmt::{closure#0} +FN:74,::fmt::{closure#1} +FN:73,::fmt::{closure#0} +FN:74,::fmt::{closure#1} +FN:36,::new +FN:54,::new_ptr +FN:70,::fmt +FN:70,::fmt +FN:54,::new_ptr +FN:14,::eq +FNDA:0,::new_ptr +FNDA:0,::fmt::{closure#1} +FNDA:0,::eq +FNDA:0,::fmt +FNDA:0,::eq +FNDA:0,::new +FNDA:0,::new +FNDA:0,::fmt::{closure#0} +FNDA:0,::fmt::{closure#0} +FNDA:0,::fmt::{closure#1} +FNDA:0,::fmt::{closure#0} +FNDA:0,::fmt::{closure#1} +FNDA:0,::new +FNDA:0,::new_ptr +FNDA:0,::fmt +FNDA:0,::fmt +FNDA:0,::new_ptr +FNDA:0,::eq +FNF:18 +FNH:0 +BRF:0 +BRH:0 +DA:14,0 +DA:36,0 +DA:37,0 +DA:38,0 +DA:39,0 +DA:40,0 +DA:41,0 +DA:42,0 +DA:43,0 +DA:44,0 +DA:45,0 +DA:46,0 +DA:47,0 +DA:48,0 +DA:49,0 +DA:50,0 +DA:54,0 +DA:55,0 +DA:56,0 +DA:57,0 +DA:58,0 +DA:59,0 +DA:60,0 +DA:61,0 +DA:62,0 +DA:63,0 +DA:64,0 +DA:65,0 +DA:66,0 +DA:70,0 +DA:71,0 +DA:72,0 +DA:73,0 +DA:74,0 +DA:75,0 +DA:76,0 +DA:77,0 +DA:78,0 +DA:79,0 +DA:80,0 +DA:81,0 +DA:82,0 +DA:83,0 +DA:84,0 +DA:85,0 +DA:86,0 +LF:46 +LH:0 +end_of_record +SF:crates/conjure_core/src/ast/symbol_table.rs +FN:8,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:8,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FN:8,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FN:15,::fmt +FN:8,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:8,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:8,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FN:8,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FN:8,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:8,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FN:8,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:8,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FN:8,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:8,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FN:15,::fmt +FN:8,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:8,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FN:15,::fmt +FN:8,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FN:8,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:8,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:8,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FN:8,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:8,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FN:8,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FN:8,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:8,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FN:8,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FN:8,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FN:8,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FN:8,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FN:8,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FNDA:1,::fmt +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FNDA:1,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_json::de::Deserializer> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:1,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str:: +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FNDA:0,::fmt +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<_> +FNDA:0,::fmt +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:1,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::expecting +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FNDA:0,<::deserialize::__Field as serde::de::Deserialize>::deserialize::<_> +FNDA:0,<::deserialize::__Visitor as serde::de::Visitor>::visit_enum::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNDA:0,<::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<_> +FNF:32 +FNH:4 +BRF:0 +BRH:0 +DA:8,1730 +DA:15,1425 +DA:16,1425 +DA:17,1050 +DA:18,375 +DA:20,1425 +LF:6 +LH:6 +end_of_record +SF:crates/conjure_core/src/error.rs +FN:8,>::from +FN:8,>::from +FN:8,::fmt +FN:8,>::from +FN:8,::source +FN:8,>::from +FN:8,::source +FN:8,::fmt +FN:8,::source +FN:8,::fmt +FN:8,>::from +FN:8,>::from +FNDA:0,>::from +FNDA:0,>::from +FNDA:0,::fmt +FNDA:0,>::from +FNDA:0,::source +FNDA:0,>::from +FNDA:0,::source +FNDA:0,::fmt +FNDA:0,::source +FNDA:0,::fmt +FNDA:0,>::from +FNDA:0,>::from +FNF:12 +FNH:0 +BRF:0 +BRH:0 +DA:8,0 +LF:1 +LH:0 +end_of_record +SF:crates/uniplate_derive/tests/macro_tests.rs +FN:4,::uniplate::{closure#7} +FN:30,macro_tests::decrease_number_of_children +FN:73,macro_tests::derive_context_tuple +FN:4,::uniplate::{closure#0} +FN:210,macro_tests::derive_children_nested_vectors +FN:18,macro_tests::increase_number_of_children +FN:159,macro_tests::derive_children_box +FN:190,macro_tests::derive_children_different_variants +FN:57,macro_tests::derive_context_vec +FN:4,::uniplate::{closure#3} +FN:166,macro_tests::derive_children_vec +FN:4,::uniplate::{closure#10} +FN:4,::uniplate::{closure#9} +FN:4,::uniplate::{closure#11} +FN:80,macro_tests::derive_context_different_variants +FN:4,::uniplate::{closure#1} +FN:176,macro_tests::derive_children_two +FN:228,macro_tests::derive_children_multiple_vecs +FN:100,macro_tests::derive_context_nested_vectors +FN:152,macro_tests::derive_children_empty +FN:139,macro_tests::box_change_child +FN:4,::uniplate::{closure#2} +FN:4,::uniplate::{closure#4} +FN:66,macro_tests::derive_context_two +FN:183,macro_tests::derive_children_tuple +FN:93,macro_tests::derive_context_nested_tuples +FN:203,macro_tests::derive_children_nested_tuples +FN:119,macro_tests::derive_context_multiple_vecs +FN:4,::uniplate::{closure#10}::{closure#0} +FN:4,::uniplate +FN:4,::uniplate::{closure#6} +FN:4,::uniplate::{closure#12} +FN:42,macro_tests::derive_context_empty +FN:4,::uniplate::{closure#5} +FN:49,macro_tests::derive_context_box +FN:4,::uniplate::{closure#8} +FNDA:1,::uniplate::{closure#7} +FNDA:1,macro_tests::decrease_number_of_children +FNDA:1,macro_tests::derive_context_tuple +FNDA:1,::uniplate::{closure#0} +FNDA:1,macro_tests::derive_children_nested_vectors +FNDA:1,macro_tests::increase_number_of_children +FNDA:1,macro_tests::derive_children_box +FNDA:1,macro_tests::derive_children_different_variants +FNDA:1,macro_tests::derive_context_vec +FNDA:1,::uniplate::{closure#3} +FNDA:1,macro_tests::derive_children_vec +FNDA:1,::uniplate::{closure#10} +FNDA:1,::uniplate::{closure#9} +FNDA:1,::uniplate::{closure#11} +FNDA:1,macro_tests::derive_context_different_variants +FNDA:1,::uniplate::{closure#1} +FNDA:1,macro_tests::derive_children_two +FNDA:1,macro_tests::derive_children_multiple_vecs +FNDA:1,macro_tests::derive_context_nested_vectors +FNDA:1,macro_tests::derive_children_empty +FNDA:1,macro_tests::box_change_child +FNDA:1,::uniplate::{closure#2} +FNDA:1,::uniplate::{closure#4} +FNDA:1,macro_tests::derive_context_two +FNDA:1,macro_tests::derive_children_tuple +FNDA:1,macro_tests::derive_context_nested_tuples +FNDA:1,macro_tests::derive_children_nested_tuples +FNDA:1,macro_tests::derive_context_multiple_vecs +FNDA:1,::uniplate::{closure#10}::{closure#0} +FNDA:1,::uniplate +FNDA:1,::uniplate::{closure#6} +FNDA:1,::uniplate::{closure#12} +FNDA:1,macro_tests::derive_context_empty +FNDA:1,::uniplate::{closure#5} +FNDA:1,macro_tests::derive_context_box +FNDA:1,::uniplate::{closure#8} +FNF:36 +FNH:36 +BRF:0 +BRH:0 +DA:4,47 +DA:18,1 +DA:19,1 +DA:20,1 +DA:21,1 +DA:22,1 +DA:23,1 +DA:24,1 +DA:25,1 +DA:26,1 +DA:27,1 +DA:30,1 +DA:31,1 +DA:32,1 +DA:33,1 +DA:34,1 +DA:35,1 +DA:36,1 +DA:37,1 +DA:38,1 +DA:39,1 +DA:42,1 +DA:43,1 +DA:44,1 +DA:45,1 +DA:46,1 +DA:49,1 +DA:50,1 +DA:51,1 +DA:52,1 +DA:53,1 +DA:54,1 +DA:57,1 +DA:58,1 +DA:59,1 +DA:60,1 +DA:61,1 +DA:62,1 +DA:63,1 +DA:66,1 +DA:67,1 +DA:68,1 +DA:69,1 +DA:70,1 +DA:73,1 +DA:74,1 +DA:75,1 +DA:76,1 +DA:77,1 +DA:80,1 +DA:81,1 +DA:82,1 +DA:83,1 +DA:84,1 +DA:85,1 +DA:86,1 +DA:87,1 +DA:88,1 +DA:89,1 +DA:90,1 +DA:93,1 +DA:94,1 +DA:95,1 +DA:96,1 +DA:97,1 +DA:100,1 +DA:101,1 +DA:102,1 +DA:103,1 +DA:104,1 +DA:105,1 +DA:106,1 +DA:107,1 +DA:108,1 +DA:109,1 +DA:110,1 +DA:111,1 +DA:112,1 +DA:113,1 +DA:114,1 +DA:115,1 +DA:116,1 +DA:119,1 +DA:120,1 +DA:121,1 +DA:122,1 +DA:123,1 +DA:124,1 +DA:125,1 +DA:126,1 +DA:127,1 +DA:128,1 +DA:129,1 +DA:130,1 +DA:131,1 +DA:132,1 +DA:133,1 +DA:134,1 +DA:135,1 +DA:136,1 +DA:139,1 +DA:140,1 +DA:141,1 +DA:142,1 +DA:143,1 +DA:144,1 +DA:145,1 +DA:146,1 +DA:147,1 +DA:148,1 +DA:149,1 +DA:152,1 +DA:153,1 +DA:154,1 +DA:155,1 +DA:156,1 +DA:159,1 +DA:160,1 +DA:161,1 +DA:162,1 +DA:163,1 +DA:166,1 +DA:167,1 +DA:168,1 +DA:169,1 +DA:170,1 +DA:171,1 +DA:172,1 +DA:173,1 +DA:176,1 +DA:177,1 +DA:178,1 +DA:179,1 +DA:180,1 +DA:183,1 +DA:184,1 +DA:185,1 +DA:186,1 +DA:187,1 +DA:190,1 +DA:191,1 +DA:192,1 +DA:193,1 +DA:194,1 +DA:195,1 +DA:196,1 +DA:197,1 +DA:198,1 +DA:199,1 +DA:200,1 +DA:203,1 +DA:204,1 +DA:205,1 +DA:206,1 +DA:207,1 +DA:210,1 +DA:211,1 +DA:212,1 +DA:213,1 +DA:214,1 +DA:215,1 +DA:216,1 +DA:217,1 +DA:218,1 +DA:219,1 +DA:220,1 +DA:221,1 +DA:222,1 +DA:223,1 +DA:224,1 +DA:225,1 +DA:228,1 +DA:229,1 +DA:230,1 +DA:231,1 +DA:232,1 +DA:233,1 +DA:234,1 +DA:235,1 +DA:236,1 +DA:237,1 +DA:238,1 +DA:239,1 +DA:240,1 +DA:241,1 +DA:242,1 +DA:243,1 +DA:244,1 +LF:188 +LH:188 +end_of_record +SF:conjure_oxide/tests/rewrite_tests.rs +FN:692,rewrite_tests::rule_distribute_not_over_and_not_changed +FN:18,rewrite_tests::rules_present +FN:71,rewrite_tests::recursive_sum_of_constants +FN:109,rewrite_tests::simplify_expression +FN:356,rewrite_tests::reduce_solve_xyz::{closure#0} +FN:546,rewrite_tests::rule_remove_constants_from_and +FN:726,rewrite_tests::rule_distribute_or_over_and +FN:938,rewrite_tests::is_simple_iteration +FN:994,rewrite_tests::eval_const_int +FN:604,rewrite_tests::rule_distribute_not_over_and +FN:489,rewrite_tests::remove_trivial_and_or +FN:648,rewrite_tests::rule_distribute_not_over_or +FN:522,rewrite_tests::rule_remove_constants_from_or +FN:52,rewrite_tests::evaluate_sum_of_constants +FN:138,rewrite_tests::rule_sum_constants +FN:914,rewrite_tests::rewrite_solve_xyz::{closure#0} +FN:1021,rewrite_tests::eval_const_ref +FN:709,rewrite_tests::rule_distribute_not_over_or_not_changed +FN:984,rewrite_tests::choose_rewrite +FN:383,rewrite_tests::rule_unwrap_nested_or +FN:1008,rewrite_tests::eval_const_and +FN:1028,rewrite_tests::eval_const_nested_ref +FN:570,rewrite_tests::remove_constants_from_or_not_changed +FN:24,rewrite_tests::sum_of_constants +FN:1127,rewrite_tests::eval_const_or +FN:455,rewrite_tests::unwrap_nested_or_not_changed +FN:472,rewrite_tests::unwrap_nested_and_not_changed +FN:926,rewrite_tests::is_simple +FN:197,rewrite_tests::rule_sum_geq +FN:360,rewrite_tests::rule_remove_double_negation +FN:419,rewrite_tests::rule_unwrap_nested_and +FN:962,rewrite_tests::apply_all_rules +FN:827,rewrite_tests::rewrite_solve_xyz +FN:587,rewrite_tests::remove_constants_from_and_not_changed +FN:1069,rewrite_tests::eval_const_eq_mixed +FN:1001,rewrite_tests::eval_const_bool +FN:1058,rewrite_tests::eval_const_eq_bool +FN:1080,rewrite_tests::eval_const_sum_mixed +FN:1093,rewrite_tests::eval_const_sum_xyz +FN:167,rewrite_tests::rule_sum_mixed +FN:1047,rewrite_tests::eval_const_eq_int +FN:238,rewrite_tests::reduce_solve_xyz +FNDA:1,rewrite_tests::rule_distribute_not_over_and_not_changed +FNDA:1,rewrite_tests::rules_present +FNDA:1,rewrite_tests::recursive_sum_of_constants +FNDA:1,rewrite_tests::simplify_expression +FNDA:1,rewrite_tests::reduce_solve_xyz::{closure#0} +FNDA:1,rewrite_tests::rule_remove_constants_from_and +FNDA:1,rewrite_tests::rule_distribute_or_over_and +FNDA:1,rewrite_tests::is_simple_iteration +FNDA:1,rewrite_tests::eval_const_int +FNDA:1,rewrite_tests::rule_distribute_not_over_and +FNDA:1,rewrite_tests::remove_trivial_and_or +FNDA:1,rewrite_tests::rule_distribute_not_over_or +FNDA:1,rewrite_tests::rule_remove_constants_from_or +FNDA:1,rewrite_tests::evaluate_sum_of_constants +FNDA:1,rewrite_tests::rule_sum_constants +FNDA:1,rewrite_tests::rewrite_solve_xyz::{closure#0} +FNDA:1,rewrite_tests::eval_const_ref +FNDA:1,rewrite_tests::rule_distribute_not_over_or_not_changed +FNDA:1,rewrite_tests::choose_rewrite +FNDA:1,rewrite_tests::rule_unwrap_nested_or +FNDA:1,rewrite_tests::eval_const_and +FNDA:1,rewrite_tests::eval_const_nested_ref +FNDA:1,rewrite_tests::remove_constants_from_or_not_changed +FNDA:1,rewrite_tests::sum_of_constants +FNDA:1,rewrite_tests::eval_const_or +FNDA:1,rewrite_tests::unwrap_nested_or_not_changed +FNDA:1,rewrite_tests::unwrap_nested_and_not_changed +FNDA:1,rewrite_tests::is_simple +FNDA:1,rewrite_tests::rule_sum_geq +FNDA:1,rewrite_tests::rule_remove_double_negation +FNDA:1,rewrite_tests::rule_unwrap_nested_and +FNDA:1,rewrite_tests::apply_all_rules +FNDA:1,rewrite_tests::rewrite_solve_xyz +FNDA:1,rewrite_tests::remove_constants_from_and_not_changed +FNDA:1,rewrite_tests::eval_const_eq_mixed +FNDA:1,rewrite_tests::eval_const_bool +FNDA:1,rewrite_tests::eval_const_eq_bool +FNDA:1,rewrite_tests::eval_const_sum_mixed +FNDA:1,rewrite_tests::eval_const_sum_xyz +FNDA:1,rewrite_tests::rule_sum_mixed +FNDA:1,rewrite_tests::eval_const_eq_int +FNDA:1,rewrite_tests::reduce_solve_xyz +FNF:42 +FNH:42 +BRF:0 +BRH:0 +DA:18,1 +DA:19,1 +DA:20,1 +DA:21,1 +DA:24,1 +DA:25,1 +DA:26,1 +DA:27,1 +DA:28,1 +DA:29,1 +DA:30,1 +DA:31,1 +DA:32,1 +DA:33,1 +DA:34,1 +DA:35,1 +DA:36,1 +DA:37,1 +DA:38,1 +DA:39,1 +DA:40,1 +DA:41,1 +DA:42,1 +DA:43,1 +DA:44,0 +DA:47,1 +DA:48,0 +DA:49,1 +DA:50,1 +DA:52,4 +DA:53,4 +DA:54,4 +DA:55,4 +DA:56,12 +DA:57,8 +DA:58,8 +DA:59,8 +DA:60,8 +DA:61,2 +DA:64,2 +DA:66,0 +DA:68,4 +DA:71,1 +DA:72,1 +DA:73,1 +DA:74,1 +DA:75,1 +DA:76,1 +DA:77,1 +DA:78,1 +DA:79,1 +DA:80,1 +DA:81,1 +DA:82,1 +DA:83,1 +DA:84,1 +DA:85,1 +DA:86,1 +DA:87,1 +DA:88,1 +DA:89,1 +DA:90,1 +DA:91,1 +DA:92,1 +DA:93,1 +DA:94,1 +DA:95,1 +DA:96,1 +DA:97,1 +DA:98,1 +DA:99,1 +DA:100,1 +DA:101,1 +DA:102,1 +DA:103,1 +DA:104,1 +DA:105,1 +DA:106,1 +DA:107,1 +DA:109,7 +DA:110,7 +DA:111,2 +DA:112,1 +DA:113,2 +DA:115,1 +DA:117,1 +DA:118,1 +DA:119,1 +DA:120,1 +DA:123,1 +DA:124,1 +DA:125,1 +DA:126,1 +DA:127,1 +DA:128,0 +DA:129,0 +DA:130,0 +DA:131,0 +DA:132,0 +DA:133,4 +DA:135,7 +DA:138,1 +DA:139,1 +DA:140,1 +DA:141,1 +DA:142,1 +DA:143,1 +DA:144,1 +DA:145,1 +DA:146,1 +DA:147,1 +DA:148,1 +DA:149,1 +DA:150,1 +DA:151,1 +DA:152,1 +DA:153,1 +DA:154,1 +DA:155,1 +DA:156,1 +DA:157,1 +DA:158,1 +DA:159,1 +DA:160,1 +DA:161,1 +DA:162,1 +DA:163,1 +DA:164,1 +DA:167,1 +DA:168,1 +DA:169,1 +DA:170,1 +DA:171,1 +DA:172,1 +DA:173,1 +DA:174,1 +DA:175,1 +DA:176,1 +DA:177,1 +DA:178,1 +DA:179,1 +DA:180,1 +DA:181,1 +DA:182,1 +DA:183,1 +DA:184,1 +DA:185,1 +DA:186,1 +DA:187,1 +DA:188,1 +DA:189,1 +DA:190,1 +DA:191,1 +DA:192,1 +DA:193,1 +DA:194,1 +DA:197,1 +DA:198,1 +DA:199,1 +DA:200,1 +DA:201,1 +DA:202,1 +DA:203,1 +DA:204,1 +DA:205,1 +DA:206,1 +DA:207,1 +DA:208,1 +DA:209,1 +DA:210,1 +DA:211,1 +DA:212,1 +DA:213,1 +DA:214,1 +DA:215,1 +DA:216,1 +DA:217,1 +DA:218,1 +DA:219,1 +DA:220,1 +DA:221,1 +DA:222,1 +DA:223,1 +DA:224,1 +DA:225,1 +DA:226,1 +DA:227,1 +DA:228,1 +DA:238,1 +DA:239,1 +DA:240,1 +DA:241,1 +DA:242,1 +DA:243,1 +DA:244,1 +DA:245,1 +DA:246,1 +DA:247,1 +DA:248,1 +DA:249,1 +DA:250,1 +DA:251,1 +DA:252,1 +DA:253,1 +DA:254,1 +DA:255,1 +DA:256,1 +DA:257,1 +DA:258,1 +DA:259,1 +DA:260,1 +DA:261,1 +DA:262,1 +DA:263,1 +DA:264,1 +DA:265,1 +DA:266,1 +DA:269,1 +DA:270,1 +DA:271,1 +DA:272,1 +DA:273,1 +DA:274,1 +DA:275,1 +DA:276,1 +DA:277,1 +DA:278,1 +DA:279,1 +DA:280,1 +DA:281,1 +DA:282,1 +DA:283,1 +DA:284,1 +DA:285,1 +DA:286,1 +DA:287,1 +DA:288,1 +DA:289,1 +DA:290,1 +DA:291,1 +DA:292,1 +DA:293,1 +DA:294,1 +DA:295,1 +DA:296,1 +DA:299,1 +DA:300,1 +DA:301,1 +DA:302,1 +DA:303,1 +DA:304,1 +DA:305,1 +DA:306,1 +DA:307,1 +DA:308,1 +DA:309,1 +DA:310,1 +DA:311,1 +DA:312,1 +DA:313,1 +DA:314,1 +DA:315,1 +DA:316,1 +DA:317,1 +DA:318,1 +DA:319,1 +DA:320,1 +DA:321,1 +DA:322,1 +DA:323,1 +DA:324,1 +DA:325,1 +DA:326,1 +DA:327,1 +DA:328,1 +DA:330,1 +DA:331,1 +DA:332,1 +DA:333,1 +DA:334,1 +DA:335,1 +DA:336,1 +DA:337,1 +DA:338,1 +DA:339,1 +DA:340,1 +DA:341,1 +DA:342,1 +DA:343,1 +DA:344,1 +DA:345,1 +DA:346,1 +DA:347,1 +DA:348,1 +DA:349,1 +DA:350,1 +DA:351,1 +DA:352,1 +DA:353,1 +DA:354,1 +DA:355,1 +DA:356,1 +DA:357,1 +DA:360,1 +DA:361,1 +DA:362,1 +DA:363,1 +DA:364,1 +DA:365,1 +DA:366,1 +DA:367,1 +DA:368,1 +DA:369,1 +DA:370,1 +DA:371,1 +DA:372,1 +DA:373,1 +DA:374,1 +DA:375,1 +DA:376,1 +DA:377,1 +DA:378,1 +DA:379,1 +DA:380,1 +DA:383,1 +DA:384,1 +DA:385,1 +DA:386,1 +DA:387,1 +DA:388,1 +DA:389,1 +DA:390,1 +DA:391,1 +DA:392,1 +DA:393,1 +DA:394,1 +DA:395,1 +DA:396,1 +DA:397,1 +DA:398,1 +DA:399,1 +DA:400,1 +DA:401,1 +DA:402,1 +DA:403,1 +DA:404,1 +DA:405,1 +DA:406,1 +DA:407,1 +DA:408,1 +DA:409,1 +DA:410,1 +DA:411,1 +DA:412,1 +DA:413,1 +DA:414,1 +DA:415,1 +DA:416,1 +DA:419,1 +DA:420,1 +DA:421,1 +DA:422,1 +DA:423,1 +DA:424,1 +DA:425,1 +DA:426,1 +DA:427,1 +DA:428,1 +DA:429,1 +DA:430,1 +DA:431,1 +DA:432,1 +DA:433,1 +DA:434,1 +DA:435,1 +DA:436,1 +DA:437,1 +DA:438,1 +DA:439,1 +DA:440,1 +DA:441,1 +DA:442,1 +DA:443,1 +DA:444,1 +DA:445,1 +DA:446,1 +DA:447,1 +DA:448,1 +DA:449,1 +DA:450,1 +DA:451,1 +DA:452,1 +DA:455,1 +DA:456,1 +DA:457,1 +DA:458,1 +DA:459,1 +DA:460,1 +DA:461,1 +DA:462,1 +DA:463,1 +DA:464,1 +DA:465,1 +DA:466,1 +DA:467,1 +DA:468,1 +DA:469,1 +DA:472,1 +DA:473,1 +DA:474,1 +DA:475,1 +DA:476,1 +DA:477,1 +DA:478,1 +DA:479,1 +DA:480,1 +DA:481,1 +DA:482,1 +DA:483,1 +DA:484,1 +DA:485,1 +DA:486,1 +DA:489,1 +DA:490,1 +DA:491,1 +DA:492,1 +DA:493,1 +DA:494,1 +DA:495,1 +DA:496,1 +DA:497,1 +DA:498,1 +DA:499,1 +DA:500,1 +DA:501,1 +DA:502,1 +DA:503,1 +DA:504,1 +DA:505,1 +DA:506,1 +DA:507,1 +DA:508,1 +DA:509,1 +DA:510,1 +DA:511,1 +DA:512,1 +DA:513,1 +DA:514,1 +DA:515,1 +DA:516,1 +DA:517,1 +DA:518,1 +DA:519,1 +DA:522,1 +DA:523,1 +DA:524,1 +DA:525,1 +DA:526,1 +DA:527,1 +DA:528,1 +DA:529,1 +DA:530,1 +DA:531,1 +DA:532,1 +DA:533,1 +DA:534,1 +DA:535,1 +DA:536,1 +DA:537,1 +DA:538,1 +DA:539,1 +DA:540,1 +DA:541,1 +DA:542,1 +DA:543,1 +DA:546,1 +DA:547,1 +DA:548,1 +DA:549,1 +DA:550,1 +DA:551,1 +DA:552,1 +DA:553,1 +DA:554,1 +DA:555,1 +DA:556,1 +DA:557,1 +DA:558,1 +DA:559,1 +DA:560,1 +DA:561,1 +DA:562,1 +DA:563,1 +DA:564,1 +DA:565,1 +DA:566,1 +DA:567,1 +DA:570,1 +DA:571,1 +DA:572,1 +DA:573,1 +DA:574,1 +DA:575,1 +DA:576,1 +DA:577,1 +DA:578,1 +DA:579,1 +DA:580,1 +DA:581,1 +DA:582,1 +DA:583,1 +DA:584,1 +DA:587,1 +DA:588,1 +DA:589,1 +DA:590,1 +DA:591,1 +DA:592,1 +DA:593,1 +DA:594,1 +DA:595,1 +DA:596,1 +DA:597,1 +DA:598,1 +DA:599,1 +DA:600,1 +DA:601,1 +DA:604,1 +DA:605,1 +DA:606,1 +DA:607,1 +DA:608,1 +DA:609,1 +DA:610,1 +DA:611,1 +DA:612,1 +DA:613,1 +DA:614,1 +DA:615,1 +DA:616,1 +DA:617,1 +DA:618,1 +DA:619,1 +DA:620,1 +DA:621,1 +DA:622,1 +DA:623,1 +DA:624,1 +DA:625,1 +DA:626,1 +DA:627,1 +DA:628,1 +DA:629,1 +DA:630,1 +DA:631,1 +DA:632,1 +DA:633,1 +DA:634,1 +DA:635,1 +DA:636,1 +DA:637,1 +DA:638,1 +DA:639,1 +DA:640,1 +DA:641,1 +DA:642,1 +DA:643,1 +DA:644,1 +DA:645,1 +DA:648,1 +DA:649,1 +DA:650,1 +DA:651,1 +DA:652,1 +DA:653,1 +DA:654,1 +DA:655,1 +DA:656,1 +DA:657,1 +DA:658,1 +DA:659,1 +DA:660,1 +DA:661,1 +DA:662,1 +DA:663,1 +DA:664,1 +DA:665,1 +DA:666,1 +DA:667,1 +DA:668,1 +DA:669,1 +DA:670,1 +DA:671,1 +DA:672,1 +DA:673,1 +DA:674,1 +DA:675,1 +DA:676,1 +DA:677,1 +DA:678,1 +DA:679,1 +DA:680,1 +DA:681,1 +DA:682,1 +DA:683,1 +DA:684,1 +DA:685,1 +DA:686,1 +DA:687,1 +DA:688,1 +DA:689,1 +DA:692,1 +DA:693,1 +DA:694,1 +DA:695,1 +DA:696,1 +DA:697,1 +DA:698,1 +DA:699,1 +DA:700,1 +DA:701,1 +DA:702,1 +DA:703,1 +DA:704,1 +DA:705,1 +DA:706,1 +DA:709,1 +DA:710,1 +DA:711,1 +DA:712,1 +DA:713,1 +DA:714,1 +DA:715,1 +DA:716,1 +DA:717,1 +DA:718,1 +DA:719,1 +DA:720,1 +DA:721,1 +DA:722,1 +DA:723,1 +DA:726,1 +DA:727,1 +DA:728,1 +DA:729,1 +DA:730,1 +DA:731,1 +DA:732,1 +DA:733,1 +DA:734,1 +DA:735,1 +DA:736,1 +DA:737,1 +DA:738,1 +DA:739,1 +DA:740,1 +DA:741,1 +DA:742,1 +DA:743,1 +DA:744,1 +DA:745,1 +DA:746,1 +DA:747,1 +DA:748,1 +DA:749,1 +DA:750,1 +DA:751,1 +DA:752,1 +DA:753,1 +DA:754,1 +DA:755,1 +DA:756,1 +DA:757,1 +DA:758,1 +DA:759,1 +DA:760,1 +DA:761,1 +DA:762,1 +DA:763,1 +DA:764,1 +DA:765,1 +DA:766,1 +DA:767,1 +DA:768,1 +DA:769,1 +DA:827,1 +DA:828,1 +DA:830,1 +DA:831,1 +DA:832,0 +DA:833,0 +DA:834,0 +DA:837,1 +DA:838,1 +DA:839,1 +DA:840,1 +DA:841,1 +DA:842,1 +DA:843,1 +DA:844,1 +DA:845,1 +DA:846,1 +DA:847,1 +DA:848,1 +DA:849,1 +DA:850,1 +DA:851,1 +DA:852,1 +DA:853,1 +DA:854,1 +DA:855,1 +DA:856,1 +DA:857,1 +DA:858,1 +DA:859,1 +DA:860,1 +DA:861,1 +DA:862,1 +DA:863,1 +DA:864,1 +DA:865,1 +DA:866,1 +DA:867,1 +DA:869,1 +DA:870,1 +DA:871,0 +DA:872,0 +DA:873,0 +DA:878,1 +DA:879,1 +DA:880,1 +DA:881,1 +DA:882,1 +DA:883,1 +DA:884,1 +DA:885,1 +DA:886,1 +DA:887,1 +DA:890,1 +DA:891,1 +DA:892,1 +DA:893,1 +DA:894,1 +DA:895,1 +DA:896,1 +DA:897,1 +DA:898,1 +DA:899,1 +DA:900,1 +DA:901,1 +DA:902,1 +DA:903,1 +DA:904,1 +DA:905,1 +DA:906,1 +DA:907,1 +DA:908,1 +DA:909,1 +DA:910,1 +DA:911,1 +DA:912,1 +DA:913,1 +DA:914,1 +DA:915,1 +DA:926,1 +DA:927,1 +DA:928,1 +DA:929,1 +DA:930,0 +DA:931,0 +DA:932,1 +DA:933,1 +DA:938,15 +DA:939,15 +DA:940,15 +DA:941,15 +DA:942,15 +DA:943,15 +DA:944,0 +DA:946,15 +DA:947,15 +DA:948,14 +DA:949,0 +DA:950,0 +DA:951,0 +DA:952,0 +DA:953,14 +DA:956,15 +DA:957,15 +DA:962,15 +DA:963,15 +DA:964,15 +DA:965,15 +DA:966,15 +DA:967,435 +DA:968,420 +DA:969,0 +DA:970,0 +DA:971,0 +DA:972,0 +DA:973,0 +DA:974,0 +DA:975,420 +DA:978,15 +DA:979,15 +DA:984,15 +DA:985,15 +DA:986,15 +DA:987,0 +DA:988,0 +DA:989,0 +DA:990,0 +DA:991,15 +DA:994,1 +DA:995,1 +DA:996,1 +DA:997,1 +DA:998,1 +DA:1001,1 +DA:1002,1 +DA:1003,1 +DA:1004,1 +DA:1005,1 +DA:1008,1 +DA:1009,1 +DA:1010,1 +DA:1011,1 +DA:1012,1 +DA:1013,1 +DA:1014,1 +DA:1015,1 +DA:1016,1 +DA:1017,1 +DA:1018,1 +DA:1021,1 +DA:1022,1 +DA:1023,1 +DA:1024,1 +DA:1025,1 +DA:1028,1 +DA:1029,1 +DA:1030,1 +DA:1031,1 +DA:1032,1 +DA:1033,1 +DA:1034,1 +DA:1035,1 +DA:1036,1 +DA:1037,1 +DA:1038,1 +DA:1039,1 +DA:1040,1 +DA:1041,1 +DA:1042,1 +DA:1043,1 +DA:1044,1 +DA:1047,1 +DA:1048,1 +DA:1049,1 +DA:1050,1 +DA:1051,1 +DA:1052,1 +DA:1053,1 +DA:1054,1 +DA:1055,1 +DA:1058,1 +DA:1059,1 +DA:1060,1 +DA:1061,1 +DA:1062,1 +DA:1063,1 +DA:1064,1 +DA:1065,1 +DA:1066,1 +DA:1069,1 +DA:1070,1 +DA:1071,1 +DA:1072,1 +DA:1073,1 +DA:1074,1 +DA:1075,1 +DA:1076,1 +DA:1077,1 +DA:1080,1 +DA:1081,1 +DA:1082,1 +DA:1083,1 +DA:1084,1 +DA:1085,1 +DA:1086,1 +DA:1087,1 +DA:1088,1 +DA:1089,1 +DA:1090,1 +DA:1093,1 +DA:1094,1 +DA:1095,1 +DA:1096,1 +DA:1097,1 +DA:1098,1 +DA:1099,1 +DA:1100,1 +DA:1101,1 +DA:1102,1 +DA:1103,1 +DA:1104,1 +DA:1105,1 +DA:1106,1 +DA:1107,1 +DA:1108,1 +DA:1109,1 +DA:1110,1 +DA:1111,1 +DA:1112,1 +DA:1113,1 +DA:1114,1 +DA:1115,1 +DA:1116,1 +DA:1117,1 +DA:1118,1 +DA:1119,1 +DA:1120,1 +DA:1121,1 +DA:1122,1 +DA:1123,1 +DA:1124,1 +DA:1127,1 +DA:1128,1 +DA:1129,1 +DA:1130,1 +DA:1131,1 +DA:1132,1 +DA:1133,1 +DA:1134,1 +DA:1135,1 +DA:1136,1 +DA:1137,1 +LF:937 +LH:906 +end_of_record +SF:crates/uniplate/src/uniplate.rs +FN:40,::children +FN:140,<_ as uniplate::uniplate::Uniplate>::one_holed_context::{closure#0} +FN:54,::transform +FN:48,<_ as uniplate::uniplate::Uniplate>::with_children +FN:31,<_ as uniplate::uniplate::Uniplate>::universe +FN:40,::children +FN:40,::children +FN:68,<_ as uniplate::uniplate::Uniplate>::rewrite +FN:103,<_ as uniplate::uniplate::Uniplate>::fold::<_> +FN:40,<_ as uniplate::uniplate::Uniplate>::children +FN:40,::children +FN:106,<_ as uniplate::uniplate::Uniplate>::fold::<_>::{closure#0} +FN:54,<_ as uniplate::uniplate::Uniplate>::transform +FN:3,::fmt +FN:48,::with_children +FN:132,<_ as uniplate::uniplate::Uniplate>::one_holed_context +FN:48,::with_children +FN:40,::children +FN:83,<_ as uniplate::uniplate::Uniplate>::descend +FNDA:0,::children +FNDA:0,<_ as uniplate::uniplate::Uniplate>::one_holed_context::{closure#0} +FNDA:1,::transform +FNDA:0,<_ as uniplate::uniplate::Uniplate>::with_children +FNDA:0,<_ as uniplate::uniplate::Uniplate>::universe +FNDA:0,::children +FNDA:1,::children +FNDA:0,<_ as uniplate::uniplate::Uniplate>::rewrite +FNDA:0,<_ as uniplate::uniplate::Uniplate>::fold::<_> +FNDA:0,<_ as uniplate::uniplate::Uniplate>::children +FNDA:1,::children +FNDA:0,<_ as uniplate::uniplate::Uniplate>::fold::<_>::{closure#0} +FNDA:0,<_ as uniplate::uniplate::Uniplate>::transform +FNDA:0,::fmt +FNDA:1,::with_children +FNDA:0,<_ as uniplate::uniplate::Uniplate>::one_holed_context +FNDA:0,::with_children +FNDA:1,::children +FNDA:0,<_ as uniplate::uniplate::Uniplate>::descend +FNF:19 +FNH:5 +BRF:0 +BRH:0 +DA:3,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:34,0 +DA:35,0 +DA:36,0 +DA:37,0 +DA:40,70395 +DA:41,70395 +DA:42,70395 +DA:48,1770 +DA:49,1770 +DA:50,1770 +DA:51,1770 +DA:54,9 +DA:55,9 +DA:56,9 +DA:57,9 +DA:58,17 +DA:59,8 +DA:60,8 +DA:63,9 +DA:64,9 +DA:65,9 +DA:68,0 +DA:69,0 +DA:70,0 +DA:71,0 +DA:72,0 +DA:73,0 +DA:74,0 +DA:77,0 +DA:78,0 +DA:79,0 +DA:83,0 +DA:84,0 +DA:85,0 +DA:86,0 +DA:87,0 +DA:88,0 +DA:103,0 +DA:104,0 +DA:105,0 +DA:106,0 +DA:107,0 +DA:108,0 +DA:132,0 +DA:133,0 +DA:134,0 +DA:135,0 +DA:136,0 +DA:137,0 +DA:138,0 +DA:139,0 +DA:140,0 +DA:141,0 +DA:142,0 +DA:143,0 +DA:144,0 +DA:145,0 +DA:146,0 +DA:147,0 +LF:63 +LH:17 +end_of_record +SF:crates/uniplate/src/lib.rs +FN:48,::uniplate::{closure#1} +FN:47,::uniplate::{closure#0} +FN:50,::uniplate::{closure#3} +FN:51,::uniplate::{closure#4} +FN:49,::uniplate::{closure#2} +FN:75,rust_out::main +FN:45,::uniplate +FN:66,rust_out::my_rule +FN:10,rust_out::main::_doctest_main_crates_uniplate_src_lib_rs_10_0 +FNDA:1,::uniplate::{closure#1} +FNDA:1,::uniplate::{closure#0} +FNDA:1,::uniplate::{closure#3} +FNDA:1,::uniplate::{closure#4} +FNDA:0,::uniplate::{closure#2} +FNDA:1,rust_out::main +FNDA:1,::uniplate +FNDA:1,rust_out::my_rule +FNDA:1,rust_out::main::_doctest_main_crates_uniplate_src_lib_rs_10_0 +FNF:9 +FNH:8 +BRF:0 +BRH:0 +DA:10,1 +DA:11,1 +DA:12,1 +DA:13,1 +DA:14,1 +DA:15,1 +DA:16,1 +DA:17,1 +DA:18,1 +DA:45,9 +DA:46,9 +DA:47,5 +DA:48,2 +DA:49,0 +DA:50,1 +DA:51,1 +DA:54,9 +DA:55,2 +DA:56,0 +DA:57,1 +DA:58,1 +DA:59,5 +DA:62,9 +DA:63,9 +DA:66,9 +DA:67,9 +DA:68,5 +DA:69,2 +DA:70,0 +DA:71,1 +DA:72,1 +DA:74,9 +DA:75,1 +DA:76,1 +DA:77,1 +DA:78,1 +DA:79,1 +DA:80,1 +DA:81,1 +DA:82,1 +DA:83,1 +DA:84,1 +DA:85,1 +DA:86,1 +DA:87,1 +DA:88,1 +DA:89,1 +LF:47 +LH:44 +end_of_record +SF:crates/conjure_core/src/parse/parse_model.rs +FN:243,conjure_core::parse::parse_model::parse_bin_op +FN:129,conjure_core::parse::parse_model::parse_int_domain::{closure#1} +FN:13,conjure_core::parse::parse_model::model_from_json +FN:129,conjure_core::parse::parse_model::parse_int_domain::{closure#1} +FN:84,conjure_core::parse::parse_model::parse_int_domain +FN:115,conjure_core::parse::parse_model::parse_int_domain::{closure#0} +FN:54,conjure_core::parse::parse_model::parse_variable +FN:223,conjure_core::parse::parse_model::parse_expression::{closure#4} +FN:220,conjure_core::parse::parse_model::parse_expression::{closure#3} +FN:84,conjure_core::parse::parse_model::parse_int_domain +FN:216,conjure_core::parse::parse_model::parse_expression::{closure#2} +FN:214,conjure_core::parse::parse_model::parse_expression::{closure#0} +FN:129,conjure_core::parse::parse_model::parse_int_domain::{closure#1} +FN:223,conjure_core::parse::parse_model::parse_expression::{closure#4} +FN:215,conjure_core::parse::parse_model::parse_expression::{closure#1} +FN:226,conjure_core::parse::parse_model::parse_expression::{closure#5} +FN:296,conjure_core::parse::parse_model::parse_constant +FN:226,conjure_core::parse::parse_model::parse_expression::{closure#5} +FN:115,conjure_core::parse::parse_model::parse_int_domain::{closure#0} +FN:216,conjure_core::parse::parse_model::parse_expression::{closure#2} +FN:226,conjure_core::parse::parse_model::parse_expression::{closure#5} +FN:263,conjure_core::parse::parse_model::parse_unary_op +FN:223,conjure_core::parse::parse_model::parse_expression::{closure#4} +FN:215,conjure_core::parse::parse_model::parse_expression::{closure#1} +FN:214,conjure_core::parse::parse_model::parse_expression::{closure#0} +FN:54,conjure_core::parse::parse_model::parse_variable +FN:216,conjure_core::parse::parse_model::parse_expression::{closure#2} +FN:220,conjure_core::parse::parse_model::parse_expression::{closure#3} +FN:263,conjure_core::parse::parse_model::parse_unary_op +FN:147,conjure_core::parse::parse_model::parse_expression +FN:13,conjure_core::parse::parse_model::model_from_json +FN:243,conjure_core::parse::parse_model::parse_bin_op +FN:243,conjure_core::parse::parse_model::parse_bin_op +FN:147,conjure_core::parse::parse_model::parse_expression +FN:296,conjure_core::parse::parse_model::parse_constant +FN:274,conjure_core::parse::parse_model::parse_vec_op +FN:296,conjure_core::parse::parse_model::parse_constant +FN:274,conjure_core::parse::parse_model::parse_vec_op +FN:263,conjure_core::parse::parse_model::parse_unary_op +FN:84,conjure_core::parse::parse_model::parse_int_domain +FN:274,conjure_core::parse::parse_model::parse_vec_op +FN:147,conjure_core::parse::parse_model::parse_expression +FN:214,conjure_core::parse::parse_model::parse_expression::{closure#0} +FN:54,conjure_core::parse::parse_model::parse_variable +FN:115,conjure_core::parse::parse_model::parse_int_domain::{closure#0} +FN:13,conjure_core::parse::parse_model::model_from_json +FN:215,conjure_core::parse::parse_model::parse_expression::{closure#1} +FN:220,conjure_core::parse::parse_model::parse_expression::{closure#3} +FNDA:1,conjure_core::parse::parse_model::parse_bin_op +FNDA:0,conjure_core::parse::parse_model::parse_int_domain::{closure#1} +FNDA:0,conjure_core::parse::parse_model::model_from_json +FNDA:0,conjure_core::parse::parse_model::parse_int_domain::{closure#1} +FNDA:0,conjure_core::parse::parse_model::parse_int_domain +FNDA:0,conjure_core::parse::parse_model::parse_int_domain::{closure#0} +FNDA:0,conjure_core::parse::parse_model::parse_variable +FNDA:0,conjure_core::parse::parse_model::parse_expression::{closure#4} +FNDA:1,conjure_core::parse::parse_model::parse_expression::{closure#3} +FNDA:1,conjure_core::parse::parse_model::parse_int_domain +FNDA:0,conjure_core::parse::parse_model::parse_expression::{closure#2} +FNDA:0,conjure_core::parse::parse_model::parse_expression::{closure#0} +FNDA:0,conjure_core::parse::parse_model::parse_int_domain::{closure#1} +FNDA:1,conjure_core::parse::parse_model::parse_expression::{closure#4} +FNDA:0,conjure_core::parse::parse_model::parse_expression::{closure#1} +FNDA:0,conjure_core::parse::parse_model::parse_expression::{closure#5} +FNDA:1,conjure_core::parse::parse_model::parse_constant +FNDA:0,conjure_core::parse::parse_model::parse_expression::{closure#5} +FNDA:0,conjure_core::parse::parse_model::parse_int_domain::{closure#0} +FNDA:0,conjure_core::parse::parse_model::parse_expression::{closure#2} +FNDA:1,conjure_core::parse::parse_model::parse_expression::{closure#5} +FNDA:0,conjure_core::parse::parse_model::parse_unary_op +FNDA:0,conjure_core::parse::parse_model::parse_expression::{closure#4} +FNDA:0,conjure_core::parse::parse_model::parse_expression::{closure#1} +FNDA:1,conjure_core::parse::parse_model::parse_expression::{closure#0} +FNDA:1,conjure_core::parse::parse_model::parse_variable +FNDA:1,conjure_core::parse::parse_model::parse_expression::{closure#2} +FNDA:0,conjure_core::parse::parse_model::parse_expression::{closure#3} +FNDA:0,conjure_core::parse::parse_model::parse_unary_op +FNDA:0,conjure_core::parse::parse_model::parse_expression +FNDA:1,conjure_core::parse::parse_model::model_from_json +FNDA:0,conjure_core::parse::parse_model::parse_bin_op +FNDA:0,conjure_core::parse::parse_model::parse_bin_op +FNDA:0,conjure_core::parse::parse_model::parse_expression +FNDA:0,conjure_core::parse::parse_model::parse_constant +FNDA:0,conjure_core::parse::parse_model::parse_vec_op +FNDA:0,conjure_core::parse::parse_model::parse_constant +FNDA:0,conjure_core::parse::parse_model::parse_vec_op +FNDA:0,conjure_core::parse::parse_model::parse_unary_op +FNDA:0,conjure_core::parse::parse_model::parse_int_domain +FNDA:1,conjure_core::parse::parse_model::parse_vec_op +FNDA:1,conjure_core::parse::parse_model::parse_expression +FNDA:0,conjure_core::parse::parse_model::parse_expression::{closure#0} +FNDA:0,conjure_core::parse::parse_model::parse_variable +FNDA:0,conjure_core::parse::parse_model::parse_int_domain::{closure#0} +FNDA:0,conjure_core::parse::parse_model::model_from_json +FNDA:1,conjure_core::parse::parse_model::parse_expression::{closure#1} +FNDA:0,conjure_core::parse::parse_model::parse_expression::{closure#3} +FNF:48 +FNH:13 +BRF:0 +BRH:0 +DA:13,180 +DA:14,180 +DA:15,180 +DA:16,180 +DA:17,180 +DA:18,180 +DA:20,735 +DA:21,555 +DA:22,555 +DA:23,555 +DA:24,555 +DA:25,555 +DA:26,555 +DA:27,555 +DA:28,555 +DA:29,555 +DA:30,555 +DA:31,375 +DA:32,375 +DA:34,180 +DA:35,180 +DA:36,180 +DA:38,0 +DA:42,180 +DA:43,180 +DA:44,180 +DA:47,0 +DA:51,180 +DA:52,180 +DA:54,375 +DA:55,375 +DA:56,375 +DA:57,375 +DA:58,375 +DA:59,375 +DA:60,375 +DA:61,375 +DA:62,375 +DA:63,375 +DA:64,375 +DA:65,375 +DA:66,375 +DA:67,375 +DA:68,375 +DA:69,375 +DA:70,375 +DA:71,375 +DA:72,375 +DA:73,375 +DA:74,375 +DA:75,375 +DA:76,105 +DA:77,0 +DA:78,0 +DA:79,0 +DA:80,0 +DA:81,375 +DA:82,375 +DA:84,270 +DA:85,270 +DA:86,270 +DA:87,270 +DA:88,270 +DA:89,270 +DA:90,270 +DA:91,540 +DA:92,270 +DA:93,270 +DA:94,270 +DA:95,270 +DA:96,270 +DA:97,270 +DA:98,270 +DA:99,270 +DA:100,270 +DA:101,270 +DA:102,270 +DA:103,270 +DA:104,270 +DA:105,270 +DA:106,270 +DA:107,270 +DA:108,270 +DA:109,540 +DA:110,540 +DA:111,540 +DA:112,540 +DA:113,540 +DA:114,540 +DA:115,540 +DA:116,0 +DA:117,540 +DA:118,540 +DA:120,270 +DA:122,0 +DA:123,0 +DA:124,0 +DA:125,0 +DA:126,0 +DA:127,0 +DA:128,0 +DA:129,0 +DA:130,0 +DA:133,0 +DA:134,0 +DA:135,0 +DA:139,270 +DA:140,270 +DA:147,840 +DA:148,840 +DA:149,840 +DA:150,840 +DA:151,840 +DA:152,840 +DA:153,840 +DA:154,840 +DA:155,840 +DA:156,840 +DA:157,840 +DA:158,840 +DA:159,840 +DA:160,840 +DA:161,840 +DA:162,840 +DA:163,840 +DA:164,840 +DA:165,840 +DA:166,840 +DA:167,840 +DA:168,840 +DA:169,840 +DA:170,840 +DA:171,840 +DA:172,840 +DA:173,840 +DA:174,840 +DA:175,840 +DA:176,840 +DA:177,840 +DA:178,840 +DA:179,840 +DA:180,840 +DA:181,840 +DA:182,840 +DA:183,840 +DA:184,840 +DA:185,840 +DA:186,840 +DA:187,840 +DA:188,840 +DA:189,840 +DA:190,840 +DA:191,840 +DA:192,840 +DA:193,840 +DA:194,840 +DA:195,840 +DA:196,840 +DA:197,840 +DA:198,840 +DA:199,840 +DA:200,840 +DA:201,840 +DA:202,840 +DA:203,840 +DA:204,840 +DA:205,840 +DA:206,840 +DA:207,840 +DA:208,840 +DA:209,840 +DA:210,840 +DA:211,840 +DA:212,840 +DA:213,840 +DA:214,1620 +DA:215,840 +DA:216,840 +DA:218,120 +DA:219,840 +DA:220,1620 +DA:221,180 +DA:223,150 +DA:224,0 +DA:226,450 +DA:227,150 +DA:229,0 +DA:231,510 +DA:232,390 +DA:233,390 +DA:234,390 +DA:235,390 +DA:236,390 +DA:238,120 +DA:239,0 +DA:241,840 +DA:243,180 +DA:244,180 +DA:245,180 +DA:246,180 +DA:249,180 +DA:251,180 +DA:253,180 +DA:254,180 +DA:255,180 +DA:256,180 +DA:257,180 +DA:259,0 +DA:261,180 +DA:263,0 +DA:264,0 +DA:265,0 +DA:266,0 +DA:267,0 +DA:268,0 +DA:270,0 +DA:271,0 +DA:272,0 +DA:274,150 +DA:275,150 +DA:276,150 +DA:277,150 +DA:278,150 +DA:279,150 +DA:281,150 +DA:282,150 +DA:283,150 +DA:284,150 +DA:285,150 +DA:286,150 +DA:287,150 +DA:288,150 +DA:289,150 +DA:290,0 +DA:292,150 +DA:294,150 +DA:296,120 +DA:297,120 +DA:298,120 +DA:299,120 +DA:300,120 +DA:302,0 +DA:303,0 +DA:304,0 +DA:305,0 +DA:306,0 +DA:310,120 +DA:312,0 +DA:314,120 +LF:249 +LH:210 +end_of_record diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/prnumber b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/prnumber new file mode 100644 index 0000000000..1b1c131282 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/prnumber @@ -0,0 +1 @@ +280 diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/src/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/src/index.html new file mode 100644 index 0000000000..e3bf4e3ede --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/src/index.html @@ -0,0 +1,74 @@ + + + + + Grcov report - solvers/chuffed/src + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
lib.rs + + 0% + + + 0% + + 0 / 46 + 0%0 / 14
+
+
+

Date: 2024-03-30 15:02

+
+
+ + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/src/lib.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/src/lib.rs.html new file mode 100644 index 0000000000..df9f3f00a2 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/src/lib.rs.html @@ -0,0 +1,1177 @@ + + + + + Grcov report - lib.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
pub mod bindings {
+
+
+
+ 2 +
+
+ +
+
+
    #![allow(warnings)]
+
+
+
+ 3 +
+
+ +
+
+
    include!(concat!(env!("OUT_DIR"), "/chuffed_bindings.rs"));
+
+
+
+ 4 +
+
+ +
+
+
}
+
+
+
+ 5 +
+
+ +
+
+

+            
+
+
+ 6 +
+
+ +
+
+
pub mod wrappers {
+
+
+
+ 7 +
+
+ +
+
+
    use core::ptr;
+
+
+
+ 8 +
+
+ +
+
+

+            
+
+
+ 9 +
+
+ +
+
+
    use crate::bindings::{
+
+
+
+ 10 +
+
+ +
+
+
        all_different, branch_IntVar, createVar, createVars, int_plus, make_vec_intvar,
+
+
+
+ 11 +
+
+ +
+
+
        output_vars1, var_sym_break, vec, ConLevel, IntVar, ValBranch, VarBranch,
+
+
+
+ 12 +
+
+ +
+
+
    };
+
+
+
+ 13 +
+
+ +
+
+

+            
+
+
+ 14 +
+
+ +
+
+
    // The signature of createVar is below for reference.
+
+
+
+ 15 +
+
+ +
+
+
    // createVar(x: *mut *mut IntVar, min: ::std::os::raw::c_int, max: ::std::os::raw::c_int, el: bool)
+
+
+
+ 16 +
+
+ +
+
+
    pub fn create_var(min: i32, max: i32, el: bool) -> *mut IntVar {
+
+
+
+ 17 +
+
+ +
+
+
        let mut ptr: *mut IntVar = ptr::null_mut();
+
+
+
+ 18 +
+
+ +
+
+

+            
+
+
+ 19 +
+
+ +
+
+
        unsafe {
+
+
+
+ 20 +
+
+ +
+
+
            createVar(&mut ptr, min, max, el);
+
+
+
+ 21 +
+
+ +
+
+
            ptr
+
+
+
+ 22 +
+
+ +
+
+
        }
+
+
+
+ 23 +
+
+ +
+
+
    }
+
+
+
+ 24 +
+
+ +
+
+

+            
+
+
+ 25 +
+
+ +
+
+
    // createVars void createVars(vec<IntVar*>& x, int n, int min, int max, bool el)
+
+
+
+ 26 +
+
+ +
+
+
    pub fn create_vars(n: i32, min: i32, max: i32, el: bool) -> *mut vec<*mut IntVar> {
+
+
+
+ 27 +
+
+ +
+
+
        let ptr: *mut vec<*mut IntVar> = unsafe { make_vec_intvar() };
+
+
+
+ 28 +
+
+ +
+
+

+            
+
+
+ 29 +
+
+ +
+
+
        unsafe {
+
+
+
+ 30 +
+
+ +
+
+
            createVars(ptr, n, min, max, el);
+
+
+
+ 31 +
+
+ +
+
+
            ptr
+
+
+
+ 32 +
+
+ +
+
+
        }
+
+
+
+ 33 +
+
+ +
+
+
    }
+
+
+
+ 34 +
+
+ +
+
+

+            
+
+
+ 35 +
+
+ +
+
+
    // void all_different(vec<IntVar*>& x, ConLevel cl)
+
+
+
+ 36 +
+
+ +
+
+
    pub unsafe fn all_different_wrapper(x: *mut vec<*mut IntVar>, cl: ConLevel) {
+
+
+
+ 37 +
+
+ +
+
+
        unsafe {
+
+
+
+ 38 +
+
+ +
+
+
            all_different(x, cl);
+
+
+
+ 39 +
+
+ +
+
+
        }
+
+
+
+ 40 +
+
+ +
+
+
    }
+
+
+
+ 41 +
+
+ +
+
+

+            
+
+
+ 42 +
+
+ +
+
+
    // void branch(vec<Branching*> x, VarBranch var_branch, ValBranch val_branch);
+
+
+
+ 43 +
+
+ +
+
+
    pub unsafe fn branch_wrapper(
+
+
+
+ 44 +
+
+ +
+
+
        x: *mut vec<*mut IntVar>,
+
+
+
+ 45 +
+
+ +
+
+
        var_branch: VarBranch,
+
+
+
+ 46 +
+
+ +
+
+
        val_branch: ValBranch,
+
+
+
+ 47 +
+
+ +
+
+
    ) {
+
+
+
+ 48 +
+
+ +
+
+
        unsafe {
+
+
+
+ 49 +
+
+ +
+
+
            branch_IntVar(x, var_branch, val_branch);
+
+
+
+ 50 +
+
+ +
+
+
        }
+
+
+
+ 51 +
+
+ +
+
+
    }
+
+
+
+ 52 +
+
+ +
+
+

+            
+
+
+ 53 +
+
+ +
+
+
    pub unsafe fn output_vars_wrapper(x: *mut vec<*mut IntVar>) {
+
+
+
+ 54 +
+
+ +
+
+
        unsafe {
+
+
+
+ 55 +
+
+ +
+
+
            // output_vars1 takes in an vec<IntVar*> instead of branching
+
+
+
+ 56 +
+
+ +
+
+
            output_vars1(x);
+
+
+
+ 57 +
+
+ +
+
+
        }
+
+
+
+ 58 +
+
+ +
+
+
    }
+
+
+
+ 59 +
+
+ +
+
+

+            
+
+
+ 60 +
+
+ +
+
+
    pub unsafe fn var_sym_break_wrapper(x: *mut vec<*mut IntVar>) {
+
+
+
+ 61 +
+
+ +
+
+
        unsafe {
+
+
+
+ 62 +
+
+ +
+
+
            var_sym_break(x);
+
+
+
+ 63 +
+
+ +
+
+
        }
+
+
+
+ 64 +
+
+ +
+
+
    }
+
+
+
+ 65 +
+
+ +
+
+

+            
+
+
+ 66 +
+
+ +
+
+
    pub unsafe fn int_plus_wrapper(x: *mut IntVar, y: *mut IntVar, z: *mut IntVar) {
+
+
+
+ 67 +
+
+ +
+
+
        unsafe {
+
+
+
+ 68 +
+
+ +
+
+
            int_plus(x, y, z);
+
+
+
+ 69 +
+
+ +
+
+
        }
+
+
+
+ 70 +
+
+ +
+
+
    }
+
+
+
+ 71 +
+
+ +
+
+
}
+
+
+
+
+
+

Date: 2024-03-30 15:02

+
+
+ + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/tests/chuffed_basic_run.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/tests/chuffed_basic_run.rs.html new file mode 100644 index 0000000000..0354278f96 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/tests/chuffed_basic_run.rs.html @@ -0,0 +1,1113 @@ + + + + + Grcov report - chuffed_basic_run.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use chuffed_rs::bindings::{
+
+
+
+ 2 +
+
+ +
+
+
    get_idx, new_dummy_problem, p_addVars, p_setcallback, vec, ConLevel_CL_DEF, IntVar,
+
+
+
+ 3 +
+
+ +
+
+
    VarBranch_VAR_INORDER, VarBranch_VAR_MIN_MIN,
+
+
+
+ 4 +
+
+ +
+
+
};
+
+
+
+ 5 +
+
+ +
+
+
use chuffed_rs::wrappers::{
+
+
+
+ 6 +
+
+ +
+
+
    all_different_wrapper, branch_wrapper, create_vars, output_vars_wrapper, var_sym_break_wrapper,
+
+
+
+ 7 +
+
+ +
+
+
};
+
+
+
+ 8 +
+
+ +
+
+

+            
+
+
+ 9 +
+
+ +
+
+
/// Creates the variable for the test problem and posts some constraints and
+
+
+
+ 10 +
+
+ +
+
+
/// branchings on it.
+
+
+
+ 11 +
+
+ +
+
+
unsafe fn post_constraints(_n: i32) -> *mut vec<*mut IntVar> {
+
+
+
+ 12 +
+
+ +
+
+
    // Create constant
+
+
+
+ 13 +
+
+ +
+
+
    let n: i32 = _n;
+
+
+
+ 14 +
+
+ +
+
+
    // Create some variables
+
+
+
+ 15 +
+
+ +
+
+
    let x: *mut vec<*mut IntVar> = create_vars(n, 0, n, false);
+
+
+
+ 16 +
+
+ +
+
+

+            
+
+
+ 17 +
+
+ +
+
+
    // Post some constraints
+
+
+
+ 18 +
+
+ +
+
+
    all_different_wrapper(x, ConLevel_CL_DEF);
+
+
+
+ 19 +
+
+ +
+
+

+            
+
+
+ 20 +
+
+ +
+
+
    // Post some branchings
+
+
+
+ 21 +
+
+ +
+
+
    branch_wrapper(x as _, VarBranch_VAR_INORDER, VarBranch_VAR_MIN_MIN);
+
+
+
+ 22 +
+
+ +
+
+

+            
+
+
+ 23 +
+
+ +
+
+
    // Declare output variables (optional)
+
+
+
+ 24 +
+
+ +
+
+
    output_vars_wrapper(x);
+
+
+
+ 25 +
+
+ +
+
+

+            
+
+
+ 26 +
+
+ +
+
+
    // Declare symmetries (optional)
+
+
+
+ 27 +
+
+ +
+
+
    var_sym_break_wrapper(x);
+
+
+
+ 28 +
+
+ +
+
+

+            
+
+
+ 29 +
+
+ +
+
+
    // Return the variable
+
+
+
+ 30 +
+
+ +
+
+
    x
+
+
+
+ 31 +
+
+ +
+
+
}
+
+
+
+ 32 +
+
+ +
+
+

+            
+
+
+ 33 +
+
+ +
+
+
/// Custom printing function for this test problem
+
+
+
+ 34 +
+
+ +
+
+
#[no_mangle]
+
+
+
+ 35 +
+
+ +
+
+
pub unsafe extern "C" fn callback(x: *mut vec<*mut IntVar>) {
+
+
+
+ 36 +
+
+ +
+
+
    print!("First output is: {}", get_idx(x, 0));
+
+
+
+ 37 +
+
+ +
+
+
}
+
+
+
+ 38 +
+
+ +
+
+

+            
+
+
+ 39 +
+
+ +
+
+
/// Basic test to make sure that running the ffi bindings and wrappers does not
+
+
+
+ 40 +
+
+ +
+
+
/// crash
+
+
+
+ 41 +
+
+ +
+
+
#[test]
+
+
+
+ 42 +
+
+ 1 +
+
+
fn run_basic_problem() {
+
+
+
+ 43 +
+
+ 1 +
+
+
    let args: Vec<String> = std::env::args().collect();
+
+
+
+ 44 +
+
+ 1 +
+
+

+            
+
+
+ 45 +
+
+ 1 +
+
+
    if args.len() != 2 {
+
+
+
+ 46 +
+
+ 1 +
+
+
        println!("Invalid number of arguments");
+
+
+
+ 47 +
+
+ 1 +
+
+
        return;
+
+
+
+ 48 +
+
+ +
+
+
    }
+
+
+
+ 49 +
+
+ +
+
+

+            
+
+
+ 50 +
+
+ +
+
+
    let n: i32 = args[1].parse().expect("Invalid input");
+
+
+
+ 51 +
+
+ +
+
+

+            
+
+
+ 52 +
+
+ +
+
+
    unsafe {
+
+
+
+ 53 +
+
+ +
+
+
        let x = post_constraints(n);
+
+
+
+ 54 +
+
+ +
+
+
        // make new dummy problem
+
+
+
+ 55 +
+
+ +
+
+
        let p = new_dummy_problem();
+
+
+
+ 56 +
+
+ +
+
+
        // Call problem.addvars()
+
+
+
+ 57 +
+
+ +
+
+
        p_addVars(p, x);
+
+
+
+ 58 +
+
+ +
+
+
        // Call problem.setcallback()
+
+
+
+ 59 +
+
+ +
+
+
        p_setcallback(p, Some(callback));
+
+
+
+ 60 +
+
+ +
+
+
        // Commented out currently as trying to print causes the assertion of
+
+
+
+ 61 +
+
+ +
+
+
        // isFixed() in IntVar::getVal() to fail.
+
+
+
+ 62 +
+
+ +
+
+
        // p_print(p);
+
+
+
+ 63 +
+
+ +
+
+

+            
+
+
+ 64 +
+
+ +
+
+
        // Pass test if no crash occurs
+
+
+
+ 65 +
+
+ +
+
+
        assert!(true);
+
+
+
+ 66 +
+
+ +
+
+
    }
+
+
+
+ 67 +
+
+ 1 +
+
+
}
+
+
+
+
+
+

Date: 2024-03-30 15:02

+
+
+ + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/tests/chuffed_cpp_run.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/tests/chuffed_cpp_run.rs.html new file mode 100644 index 0000000000..f1f9d50f88 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/tests/chuffed_cpp_run.rs.html @@ -0,0 +1,265 @@ + + + + + Grcov report - chuffed_cpp_run.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use chuffed_rs::bindings::{new_xyz_problem, solve_xyz};
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
#[test]
+
+
+
+ 4 +
+
+ 1 +
+
+
fn run_cpp_problem() {
+
+
+
+ 5 +
+
+ 1 +
+
+
    let n: i32 = 1;
+
+
+
+ 6 +
+
+ 1 +
+
+

+            
+
+
+ 7 +
+
+ 1 +
+
+
    unsafe {
+
+
+
+ 8 +
+
+ 1 +
+
+
        let p = new_xyz_problem(n);
+
+
+
+ 9 +
+
+ 1 +
+
+
        solve_xyz(p);
+
+
+
+ 10 +
+
+ 1 +
+
+

+            
+
+
+ 11 +
+
+ 1 +
+
+
        // Pass test if no crash occurs
+
+
+
+ 12 +
+
+ 1 +
+
+
        assert!(true);
+
+
+
+ 13 +
+
+ +
+
+
    }
+
+
+
+ 14 +
+
+ 1 +
+
+
}
+
+
+
+
+
+

Date: 2024-03-30 15:02

+
+
+ + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/tests/dummy_test.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/tests/dummy_test.rs.html new file mode 100644 index 0000000000..1e553cc953 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/tests/dummy_test.rs.html @@ -0,0 +1,105 @@ + + + + + Grcov report - dummy_test.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
#[test]
+
+
+
+ 2 +
+
+ 1 +
+
+
fn dummy() {
+
+
+
+ 3 +
+
+ 1 +
+
+
    assert_eq!(1, 1);
+
+
+
+ 4 +
+
+ 1 +
+
+
}
+
+
+
+
+
+

Date: 2024-03-30 15:02

+
+
+ + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/tests/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/tests/index.html new file mode 100644 index 0000000000..2be1b3e7a7 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/chuffed/tests/index.html @@ -0,0 +1,122 @@ + + + + + Grcov report - solvers/chuffed/tests + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
chuffed_basic_run.rs + + 14.29% + + + 14.29% + + 7 / 49 + 33.33%1 / 3
chuffed_cpp_run.rs + + 100% + + + 100% + + 10 / 10 + 100%1 / 1
dummy_test.rs + + 100% + + + 100% + + 3 / 3 + 100%1 / 1
+
+
+

Date: 2024-03-30 15:02

+
+
+ + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/kissat/src/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/kissat/src/index.html new file mode 100644 index 0000000000..175c837738 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/kissat/src/index.html @@ -0,0 +1,74 @@ + + + + + Grcov report - solvers/kissat/src + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
lib.rs + + 96% + + + 96% + + 24 / 25 + 100%1 / 1
+
+
+

Date: 2024-03-30 15:02

+
+
+ + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/kissat/src/lib.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/kissat/src/lib.rs.html new file mode 100644 index 0000000000..36e96cabac --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/kissat/src/lib.rs.html @@ -0,0 +1,537 @@ + + + + + Grcov report - lib.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
#[cfg(test)]
+
+
+
+ 2 +
+
+ +
+
+
#[test]
+
+
+
+ 3 +
+
+ 1 +
+
+
fn test1() {
+
+
+
+ 4 +
+
+ 1 +
+
+
    use kissat_rs::Assignment;
+
+
+
+ 5 +
+
+ 1 +
+
+
    use kissat_rs::Solver;
+
+
+
+ 6 +
+
+ 1 +
+
+

+            
+
+
+ 7 +
+
+ 1 +
+
+
    // Define three literals used in both formulae.
+
+
+
+ 8 +
+
+ 1 +
+
+
    let x = 1;
+
+
+
+ 9 +
+
+ 1 +
+
+
    let y = 2;
+
+
+
+ 10 +
+
+ 1 +
+
+
    let z = 3;
+
+
+
+ 11 +
+
+ 1 +
+
+

+            
+
+
+ 12 +
+
+ 1 +
+
+
    // Construct a formula from clauses (i.e. an iterator over literals).
+
+
+
+ 13 +
+
+ 1 +
+
+
    // (~x || y) && (~y || z) && (x || ~z) && (x || y || z)
+
+
+
+ 14 +
+
+ 1 +
+
+
    let formula1 = vec![vec![-x, y], vec![-y, z], vec![x, -z], vec![x, y, z]];
+
+
+
+ 15 +
+
+ 1 +
+
+
    let satisfying_assignment = Solver::solve_formula(formula1).unwrap();
+
+
+
+ 16 +
+
+ +
+
+

+            
+
+
+ 17 +
+
+ +
+
+
    // The formula from above is satisfied by the assignment: x -> True, y -> True, z -> True
+
+
+
+ 18 +
+
+ 1 +
+
+
    if let Some(assignments) = satisfying_assignment {
+
+
+
+ 19 +
+
+ 1 +
+
+
        assert_eq!(assignments.get(&x).unwrap(), &Some(Assignment::True));
+
+
+
+ 20 +
+
+ 1 +
+
+
        assert_eq!(assignments.get(&y).unwrap(), &Some(Assignment::True));
+
+
+
+ 21 +
+
+ 1 +
+
+
        assert_eq!(assignments.get(&z).unwrap(), &Some(Assignment::True));
+
+
+
+ 22 +
+
+ +
+
+
    }
+
+
+
+ 23 +
+
+ +
+
+

+            
+
+
+ 24 +
+
+ +
+
+
    // (x || y || ~z) && ~x && (x || y || z) && (x || ~y)
+
+
+
+ 25 +
+
+ 1 +
+
+
    let formula2 = vec![vec![x, y, -z], vec![-x], vec![x, y, z], vec![x, -y]];
+
+
+
+ 26 +
+
+ 1 +
+
+
    let unsat_result = Solver::solve_formula(formula2).unwrap();
+
+
+
+ 27 +
+
+ 1 +
+
+

+            
+
+
+ 28 +
+
+ 1 +
+
+
    // The second formula is unsatisfiable.
+
+
+
+ 29 +
+
+ 1 +
+
+
    // This can for example be proved by resolution.
+
+
+
+ 30 +
+
+ 1 +
+
+
    assert_eq!(unsat_result, None);
+
+
+
+ 31 +
+
+ 1 +
+
+
}
+
+
+
+
+
+

Date: 2024-03-30 15:02

+
+
+ + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/ast.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/ast.rs.html new file mode 100644 index 0000000000..983f6cbfce --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/ast.rs.html @@ -0,0 +1,3257 @@ + + + + + Grcov report - ast.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
//! Types used for representing Minion models in Rust.
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
use std::collections::HashMap;
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ +
+
+
pub type VarName = String;
+
+
+
+ 6 +
+
+ +
+
+
pub type Tuple = (Constant, Constant);
+
+
+
+ 7 +
+
+ +
+
+
pub type TwoVars = (Var, Var);
+
+
+
+ 8 +
+
+ +
+
+

+            
+
+
+ 9 +
+
+ +
+
+
/// A Minion model.
+
+
+
+ 10 +
+
+ +
+
+
#[non_exhaustive]
+
+
+
+ 11 +
+
+ +
+
+
#[derive(Debug, Clone, PartialEq, Eq)]
+
+
+
+ 12 +
+
+ +
+
+
pub struct Model {
+
+
+
+ 13 +
+
+ +
+
+
    pub named_variables: SymbolTable,
+
+
+
+ 14 +
+
+ +
+
+
    pub constraints: Vec<Constraint>,
+
+
+
+ 15 +
+
+ +
+
+
}
+
+
+
+ 16 +
+
+ +
+
+

+            
+
+
+ 17 +
+
+ +
+
+
impl Model {
+
+
+
+ 18 +
+
+ +
+
+
    /// Creates an empty Minion model.
+
+
+
+ 19 +
+
+ 285 +
+
+
    pub fn new() -> Model {
+
+
+
+ 20 +
+
+ 285 +
+
+
        Model {
+
+
+
+ 21 +
+
+ 285 +
+
+
            named_variables: SymbolTable::new(),
+
+
+
+ 22 +
+
+ 285 +
+
+
            constraints: Vec::new(),
+
+
+
+ 23 +
+
+ 285 +
+
+
        }
+
+
+
+ 24 +
+
+ 285 +
+
+
    }
+
+
+
+ 25 +
+
+ +
+
+
}
+
+
+
+ 26 +
+
+ +
+
+

+            
+
+
+ 27 +
+
+ +
+
+
impl Default for Model {
+
+
+
+ 28 +
+
+ +
+
+
    fn default() -> Self {
+
+
+
+ 29 +
+
+ +
+
+
        Self::new()
+
+
+
+ 30 +
+
+ +
+
+
    }
+
+
+
+ 31 +
+
+ +
+
+
}
+
+
+
+ 32 +
+
+ +
+
+

+            
+
+
+ 33 +
+
+ +
+
+
/// All supported Minion constraints.
+
+
+
+ 34 +
+
+ +
+
+
#[non_exhaustive]
+
+
+
+ 35 +
+
+ +
+
+
#[derive(Debug, Clone, PartialEq, Eq)]
+
+
+
+ 36 +
+
+ +
+
+
pub enum Constraint {
+
+
+
+ 37 +
+
+ +
+
+
    Difference(TwoVars, Var),
+
+
+
+ 38 +
+
+ +
+
+
    Div(TwoVars, Var),
+
+
+
+ 39 +
+
+ +
+
+
    DivUndefZero(TwoVars, Var),
+
+
+
+ 40 +
+
+ +
+
+
    Modulo(TwoVars, Var),
+
+
+
+ 41 +
+
+ +
+
+
    ModuloUndefZero(TwoVars, Var),
+
+
+
+ 42 +
+
+ +
+
+
    Pow(TwoVars, Var),
+
+
+
+ 43 +
+
+ +
+
+
    Product(TwoVars, Var),
+
+
+
+ 44 +
+
+ +
+
+
    WeightedSumGeq(Vec<Constant>, Vec<Var>, Var),
+
+
+
+ 45 +
+
+ +
+
+
    WeightedSumLeq(Vec<Constant>, Vec<Var>, Var),
+
+
+
+ 46 +
+
+ +
+
+
    CheckAssign(Box<Constraint>),
+
+
+
+ 47 +
+
+ +
+
+
    CheckGsa(Box<Constraint>),
+
+
+
+ 48 +
+
+ +
+
+
    ForwardChecking(Box<Constraint>),
+
+
+
+ 49 +
+
+ +
+
+
    Reify(Box<Constraint>, Var),
+
+
+
+ 50 +
+
+ +
+
+
    ReifyImply(Box<Constraint>, Var),
+
+
+
+ 51 +
+
+ +
+
+
    ReifyImplyQuick(Box<Constraint>, Var),
+
+
+
+ 52 +
+
+ +
+
+
    WatchedAnd(Vec<Constraint>),
+
+
+
+ 53 +
+
+ +
+
+
    WatchedOr(Vec<Constraint>),
+
+
+
+ 54 +
+
+ +
+
+
    GacAllDiff(Vec<Var>),
+
+
+
+ 55 +
+
+ +
+
+
    AllDiff(Vec<Var>),
+
+
+
+ 56 +
+
+ +
+
+
    AllDiffMatrix(Vec<Var>, Constant),
+
+
+
+ 57 +
+
+ +
+
+
    WatchSumGeq(Vec<Var>, Constant),
+
+
+
+ 58 +
+
+ +
+
+
    WatchSumLeq(Vec<Var>, Constant),
+
+
+
+ 59 +
+
+ +
+
+
    OccurrenceGeq(Vec<Var>, Constant, Constant),
+
+
+
+ 60 +
+
+ +
+
+
    OccurrenceLeq(Vec<Var>, Constant, Constant),
+
+
+
+ 61 +
+
+ +
+
+
    Occurrence(Vec<Var>, Constant, Var),
+
+
+
+ 62 +
+
+ +
+
+
    LitSumGeq(Vec<Var>, Vec<Constant>, Constant),
+
+
+
+ 63 +
+
+ +
+
+
    Gcc(Vec<Var>, Vec<Constant>, Vec<Var>),
+
+
+
+ 64 +
+
+ +
+
+
    GccWeak(Vec<Var>, Vec<Constant>, Vec<Var>),
+
+
+
+ 65 +
+
+ +
+
+
    LexLeqRv(Vec<Var>, Vec<Var>),
+
+
+
+ 66 +
+
+ +
+
+
    LexLeq(Vec<Var>, Vec<Var>),
+
+
+
+ 67 +
+
+ +
+
+
    LexLess(Vec<Var>, Vec<Var>),
+
+
+
+ 68 +
+
+ +
+
+
    LexLeqQuick(Vec<Var>, Vec<Var>),
+
+
+
+ 69 +
+
+ +
+
+
    LexLessQuick(Vec<Var>, Vec<Var>),
+
+
+
+ 70 +
+
+ +
+
+
    WatchVecNeq(Vec<Var>, Vec<Var>),
+
+
+
+ 71 +
+
+ +
+
+
    WatchVecExistsLess(Vec<Var>, Vec<Var>),
+
+
+
+ 72 +
+
+ +
+
+
    Hamming(Vec<Var>, Vec<Var>, Constant),
+
+
+
+ 73 +
+
+ +
+
+
    NotHamming(Vec<Var>, Vec<Var>, Constant),
+
+
+
+ 74 +
+
+ +
+
+
    FrameUpdate(Vec<Var>, Vec<Var>, Vec<Var>, Vec<Var>, Constant),
+
+
+
+ 75 +
+
+ +
+
+
    //HaggisGac(Vec<Var>,Vec<
+
+
+
+ 76 +
+
+ +
+
+
    //HaggisGacStable
+
+
+
+ 77 +
+
+ +
+
+
    //ShortStr2
+
+
+
+ 78 +
+
+ +
+
+
    //ShortcTupleStr2
+
+
+
+ 79 +
+
+ +
+
+
    NegativeTable(Vec<Var>, Vec<Tuple>),
+
+
+
+ 80 +
+
+ +
+
+
    Table(Vec<Var>, Vec<Tuple>),
+
+
+
+ 81 +
+
+ +
+
+
    GacSchema(Vec<Var>, Vec<Tuple>),
+
+
+
+ 82 +
+
+ +
+
+
    LightTable(Vec<Var>, Vec<Tuple>),
+
+
+
+ 83 +
+
+ +
+
+
    Mddc(Vec<Var>, Vec<Tuple>),
+
+
+
+ 84 +
+
+ +
+
+
    NegativeMddc(Vec<Var>, Vec<Tuple>),
+
+
+
+ 85 +
+
+ +
+
+
    Str2Plus(Vec<Var>, Var),
+
+
+
+ 86 +
+
+ +
+
+
    Max(Vec<Var>, Var),
+
+
+
+ 87 +
+
+ +
+
+
    Min(Vec<Var>, Var),
+
+
+
+ 88 +
+
+ +
+
+
    NvalueGeq(Vec<Var>, Var),
+
+
+
+ 89 +
+
+ +
+
+
    NvalueLeq(Vec<Var>, Var),
+
+
+
+ 90 +
+
+ +
+
+
    SumLeq(Vec<Var>, Var),
+
+
+
+ 91 +
+
+ +
+
+
    SumGeq(Vec<Var>, Var),
+
+
+
+ 92 +
+
+ +
+
+
    Element(Vec<Var>, Var, Var),
+
+
+
+ 93 +
+
+ +
+
+
    ElementOne(Vec<Var>, Var, Var),
+
+
+
+ 94 +
+
+ +
+
+
    ElementUndefZero(Vec<Var>, Var, Var),
+
+
+
+ 95 +
+
+ +
+
+
    WatchElement(Vec<Var>, Var, Var),
+
+
+
+ 96 +
+
+ +
+
+
    WatchElementOne(Vec<Var>, Var, Var),
+
+
+
+ 97 +
+
+ +
+
+
    WatchElementOneUndefZero(Vec<Var>, Var, Var),
+
+
+
+ 98 +
+
+ +
+
+
    WatchElementUndefZero(Vec<Var>, Var, Var),
+
+
+
+ 99 +
+
+ +
+
+
    WLiteral(Var, Constant),
+
+
+
+ 100 +
+
+ +
+
+
    WNotLiteral(Var, Constant),
+
+
+
+ 101 +
+
+ +
+
+
    WInIntervalSet(Var, Vec<Constant>),
+
+
+
+ 102 +
+
+ +
+
+
    WInRange(Var, Vec<Constant>),
+
+
+
+ 103 +
+
+ +
+
+
    WInset(Var, Vec<Constant>),
+
+
+
+ 104 +
+
+ +
+
+
    WNotInRange(Var, Vec<Constant>),
+
+
+
+ 105 +
+
+ +
+
+
    WNotInset(Var, Vec<Constant>),
+
+
+
+ 106 +
+
+ +
+
+
    Abs(Var, Var),
+
+
+
+ 107 +
+
+ +
+
+
    DisEq(Var, Var),
+
+
+
+ 108 +
+
+ +
+
+
    Eq(Var, Var),
+
+
+
+ 109 +
+
+ +
+
+
    MinusEq(Var, Var),
+
+
+
+ 110 +
+
+ +
+
+
    GacEq(Var, Var),
+
+
+
+ 111 +
+
+ +
+
+
    WatchLess(Var, Var),
+
+
+
+ 112 +
+
+ +
+
+
    WatchNeq(Var, Var),
+
+
+
+ 113 +
+
+ +
+
+
    Ineq(Var, Var, Constant),
+
+
+
+ 114 +
+
+ +
+
+
}
+
+
+
+ 115 +
+
+ +
+
+

+            
+
+
+ 116 +
+
+ +
+
+
/// Representation of a Minion Variable.
+
+
+
+ 117 +
+
+ +
+
+
///
+
+
+
+ 118 +
+
+ +
+
+
/// A variable can either be a named variable, or an anomynous "constant as a variable".
+
+
+
+ 119 +
+
+ +
+
+
///
+
+
+
+ 120 +
+
+ +
+
+
/// The latter is not stored in the symbol table, or counted in Minions internal list of all
+
+
+
+ 121 +
+
+ +
+
+
/// variables, but is used to allow the use of a constant in the place of a variable in a
+
+
+
+ 122 +
+
+ +
+
+
/// constraint.
+
+
+
+ 123 +
+
+ +
+
+
#[derive(Debug, Clone, Eq, PartialEq)]
+
+
+
+ 124 +
+
+ +
+
+
pub enum Var {
+
+
+
+ 125 +
+
+ +
+
+
    NameRef(VarName),
+
+
+
+ 126 +
+
+ +
+
+
    ConstantAsVar(i32),
+
+
+
+ 127 +
+
+ +
+
+
}
+
+
+
+ 128 +
+
+ +
+
+

+            
+
+
+ 129 +
+
+ +
+
+
/// Representation of a Minion constant.
+
+
+
+ 130 +
+
+ +
+
+
#[non_exhaustive]
+
+
+
+ 131 +
+
+ +
+
+
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
+
+
+
+ 132 +
+
+ +
+
+
pub enum Constant {
+
+
+
+ 133 +
+
+ +
+
+
    Bool(bool),
+
+
+
+ 134 +
+
+ +
+
+
    Integer(i32),
+
+
+
+ 135 +
+
+ +
+
+
}
+
+
+
+ 136 +
+
+ +
+
+

+            
+
+
+ 137 +
+
+ +
+
+
/// Representation of variable domains.
+
+
+
+ 138 +
+
+ +
+
+
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+
+
+
+ 139 +
+
+ +
+
+
#[non_exhaustive]
+
+
+
+ 140 +
+
+ +
+
+
pub enum VarDomain {
+
+
+
+ 141 +
+
+ +
+
+
    Bound(i32, i32),
+
+
+
+ 142 +
+
+ +
+
+
    Discrete(i32, i32),
+
+
+
+ 143 +
+
+ +
+
+
    SparseBound(i32, i32),
+
+
+
+ 144 +
+
+ +
+
+
    Bool,
+
+
+
+ 145 +
+
+ +
+
+
}
+
+
+
+ 146 +
+
+ +
+
+

+            
+
+
+ 147 +
+
+ +
+
+
#[derive(Debug, Clone, Eq, PartialEq)]
+
+
+
+ 148 +
+
+ +
+
+
#[non_exhaustive]
+
+
+
+ 149 +
+
+ +
+
+
/// Stores all named variables in a Minion model alongside their domains.
+
+
+
+ 150 +
+
+ +
+
+
///
+
+
+
+ 151 +
+
+ +
+
+
/// Named variables referenced in [constraints](Constraint) must be in the symbol table for the
+
+
+
+ 152 +
+
+ +
+
+
/// model to be valid. In the future, this will raise some sort of type error.
+
+
+
+ 153 +
+
+ +
+
+
pub struct SymbolTable {
+
+
+
+ 154 +
+
+ +
+
+
    table: HashMap<VarName, VarDomain>,
+
+
+
+ 155 +
+
+ +
+
+

+            
+
+
+ 156 +
+
+ +
+
+
    // for now doubles both as Minion's SearchOrder and print order
+
+
+
+ 157 +
+
+ +
+
+
    var_order: Vec<VarName>,
+
+
+
+ 158 +
+
+ +
+
+
}
+
+
+
+ 159 +
+
+ +
+
+

+            
+
+
+ 160 +
+
+ +
+
+
impl SymbolTable {
+
+
+
+ 161 +
+
+ 285 +
+
+
    fn new() -> SymbolTable {
+
+
+
+ 162 +
+
+ 285 +
+
+
        SymbolTable {
+
+
+
+ 163 +
+
+ 285 +
+
+
            table: HashMap::new(),
+
+
+
+ 164 +
+
+ 285 +
+
+
            var_order: Vec::new(),
+
+
+
+ 165 +
+
+ 285 +
+
+
        }
+
+
+
+ 166 +
+
+ 285 +
+
+
    }
+
+
+
+ 167 +
+
+ +
+
+

+            
+
+
+ 168 +
+
+ +
+
+
    /// Creates a new variable and adds it to the symbol table.
+
+
+
+ 169 +
+
+ +
+
+
    ///
+
+
+
+ 170 +
+
+ +
+
+
    /// # Returns
+
+
+
+ 171 +
+
+ +
+
+
    ///
+
+
+
+ 172 +
+
+ +
+
+
    /// If a variable already exists with the given name, `None` is returned.
+
+
+
+ 173 +
+
+ 760 +
+
+
    pub fn add_var(&mut self, name: VarName, vartype: VarDomain) -> Option<()> {
+
+
+
+ 174 +
+
+ 760 +
+
+
        if self.table.contains_key(&name) {
+
+
+
+ 175 +
+
+ +
+
+
            return None;
+
+
+
+ 176 +
+
+ 760 +
+
+
        }
+
+
+
+ 177 +
+
+ 760 +
+
+

+            
+
+
+ 178 +
+
+ 760 +
+
+
        self.table.insert(name.clone(), vartype);
+
+
+
+ 179 +
+
+ 760 +
+
+
        self.var_order.push(name);
+
+
+
+ 180 +
+
+ 760 +
+
+

+            
+
+
+ 181 +
+
+ 760 +
+
+
        Some(())
+
+
+
+ 182 +
+
+ 760 +
+
+
    }
+
+
+
+ 183 +
+
+ +
+
+

+            
+
+
+ 184 +
+
+ +
+
+
    /// Gets the domain of a named variable.
+
+
+
+ 185 +
+
+ +
+
+
    ///
+
+
+
+ 186 +
+
+ +
+
+
    /// # Returns
+
+
+
+ 187 +
+
+ +
+
+
    ///
+
+
+
+ 188 +
+
+ +
+
+
    /// `None` if no variable is known by that name.
+
+
+
+ 189 +
+
+ 760 +
+
+
    pub fn get_vartype(&self, name: VarName) -> Option<VarDomain> {
+
+
+
+ 190 +
+
+ 760 +
+
+
        self.table.get(&name).cloned()
+
+
+
+ 191 +
+
+ 760 +
+
+
    }
+
+
+
+ 192 +
+
+ +
+
+

+            
+
+
+ 193 +
+
+ +
+
+
    /// Gets the canonical ordering of variables.
+
+
+
+ 194 +
+
+ 285 +
+
+
    pub fn get_variable_order(&self) -> Vec<VarName> {
+
+
+
+ 195 +
+
+ 285 +
+
+
        self.var_order.clone()
+
+
+
+ 196 +
+
+ 285 +
+
+
    }
+
+
+
+ 197 +
+
+ +
+
+

+            
+
+
+ 198 +
+
+ +
+
+
    pub fn contains(&self, name: VarName) -> bool {
+
+
+
+ 199 +
+
+ +
+
+
        self.table.contains_key(&name)
+
+
+
+ 200 +
+
+ +
+
+
    }
+
+
+
+ 201 +
+
+ +
+
+
}
+
+
+
+
+
+

Date: 2024-03-30 15:02

+
+
+ + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/error.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/error.rs.html new file mode 100644 index 0000000000..36a57eadb9 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/error.rs.html @@ -0,0 +1,905 @@ + + + + + Grcov report - error.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
//! Error types.
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
use thiserror::Error;
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ +
+
+
use crate::ffi;
+
+
+
+ 6 +
+
+ +
+
+

+            
+
+
+ 7 +
+
+ +
+
+
/// Wraps all error types returned by `minion_rs`.
+
+
+
+ 8 +
+
+ +
+
+
#[derive(Debug, Error)]
+
+
+
+ 9 +
+
+ +
+
+
#[non_exhaustive]
+
+
+
+ 10 +
+
+ +
+
+
pub enum MinionError {
+
+
+
+ 11 +
+
+ +
+
+
    /// An error has occurred during the execution of Minion.
+
+
+
+ 12 +
+
+ +
+
+
    #[error("runtime error: `{0}.to_string()`")]
+
+
+
+ 13 +
+
+ +
+
+
    RuntimeError(#[from] RuntimeError),
+
+
+
+ 14 +
+
+ +
+
+

+            
+
+
+ 15 +
+
+ +
+
+
    /// The input model uses Minion features that are not yet implemented in `minion_rs`.
+
+
+
+ 16 +
+
+ +
+
+
    #[error("not implemented: {0}")]
+
+
+
+ 17 +
+
+ +
+
+
    NotImplemented(String),
+
+
+
+ 18 +
+
+ +
+
+

+            
+
+
+ 19 +
+
+ +
+
+
    /// Catch-all error.
+
+
+
+ 20 +
+
+ +
+
+
    #[error(transparent)]
+
+
+
+ 21 +
+
+ +
+
+
    Other(#[from] anyhow::Error), // source and Display delegate to anyhow::Error
+
+
+
+ 22 +
+
+ +
+
+
}
+
+
+
+ 23 +
+
+ +
+
+

+            
+
+
+ 24 +
+
+ +
+
+
/// Errors thrown by Minion during execution.
+
+
+
+ 25 +
+
+ +
+
+
///
+
+
+
+ 26 +
+
+ +
+
+
/// These represent internal Minion C++ exceptions translated into Rust.
+
+
+
+ 27 +
+
+ +
+
+
///
+
+
+
+ 28 +
+
+ +
+
+
/// Invalid usage of this library should throw an error before Minion is even run. Therefore, these
+
+
+
+ 29 +
+
+ +
+
+
/// should be quite rare. Consider creating an issue on
+
+
+
+ 30 +
+
+ +
+
+
/// [Github](https://github.com/conjure-cp/conjure-oxide) if these occur regularly!
+
+
+
+ 31 +
+
+ +
+
+
#[derive(Debug, Error, Eq, PartialEq)]
+
+
+
+ 32 +
+
+ +
+
+
#[non_exhaustive]
+
+
+
+ 33 +
+
+ +
+
+
pub enum RuntimeError {
+
+
+
+ 34 +
+
+ +
+
+
    // These closely follow the ReturnCodes found in Minion's libwrapper.cpp.
+
+
+
+ 35 +
+
+ +
+
+
    /// The model given to Minion is invalid.
+
+
+
+ 36 +
+
+ +
+
+
    #[error("the given instance is invalid")]
+
+
+
+ 37 +
+
+ +
+
+
    InvalidInstance,
+
+
+
+ 38 +
+
+ +
+
+

+            
+
+
+ 39 +
+
+ +
+
+
    /// An unknown error has occurred.
+
+
+
+ 40 +
+
+ +
+
+
    #[error("an unknown error has occurred while running minion")]
+
+
+
+ 41 +
+
+ +
+
+
    UnknownError,
+
+
+
+ 42 +
+
+ +
+
+
}
+
+
+
+ 43 +
+
+ +
+
+

+            
+
+
+ 44 +
+
+ +
+
+
// Minion's ReturnCodes are passed over FFI as ints.
+
+
+
+ 45 +
+
+ +
+
+
// Convert them to their appropriate error.
+
+
+
+ 46 +
+
+ +
+
+
impl From<u32> for RuntimeError {
+
+
+
+ 47 +
+
+ +
+
+
    fn from(return_code: u32) -> Self {
+
+
+
+ 48 +
+
+ +
+
+
        match return_code {
+
+
+
+ 49 +
+
+ +
+
+
            #[allow(non_upper_case_globals)]
+
+
+
+ 50 +
+
+ +
+
+
            ffi::ReturnCodes_INVALID_INSTANCE => RuntimeError::InvalidInstance,
+
+
+
+ 51 +
+
+ +
+
+
            _ => RuntimeError::UnknownError,
+
+
+
+ 52 +
+
+ +
+
+
        }
+
+
+
+ 53 +
+
+ +
+
+
    }
+
+
+
+ 54 +
+
+ +
+
+
}
+
+
+
+
+
+

Date: 2024-03-30 15:02

+
+
+ + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/ffi.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/ffi.rs.html new file mode 100644 index 0000000000..605930e646 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/ffi.rs.html @@ -0,0 +1,1721 @@ + + + + + Grcov report - ffi.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
#![allow(warnings)]
+
+
+
+ 2 +
+
+ +
+
+
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
+
+
+
+ 3 +
+
+ +
+
+

+            
+
+
+ 4 +
+
+ +
+
+
#[cfg(test)]
+
+
+
+ 5 +
+
+ +
+
+
mod tests {
+
+
+
+ 6 +
+
+ +
+
+
    use std::ffi::CString;
+
+
+
+ 7 +
+
+ +
+
+

+            
+
+
+ 8 +
+
+ +
+
+
    use super::*;
+
+
+
+ 9 +
+
+ +
+
+

+            
+
+
+ 10 +
+
+ +
+
+
    // solutions
+
+
+
+ 11 +
+
+ +
+
+
    static mut X_VAL: i32 = 0;
+
+
+
+ 12 +
+
+ +
+
+
    static mut Y_VAL: i32 = 0;
+
+
+
+ 13 +
+
+ +
+
+
    static mut Z_VAL: i32 = 0;
+
+
+
+ 14 +
+
+ +
+
+

+            
+
+
+ 15 +
+
+ +
+
+
    #[no_mangle]
+
+
+
+ 16 +
+
+ 1 +
+
+
    pub extern "C" fn hello_from_rust() -> bool {
+
+
+
+ 17 +
+
+ 1 +
+
+
        unsafe {
+
+
+
+ 18 +
+
+ 1 +
+
+
            X_VAL = printMatrix_getValue(0) as _;
+
+
+
+ 19 +
+
+ 1 +
+
+
            Y_VAL = printMatrix_getValue(1) as _;
+
+
+
+ 20 +
+
+ 1 +
+
+
            Z_VAL = printMatrix_getValue(2) as _;
+
+
+
+ 21 +
+
+ 1 +
+
+
            return true;
+
+
+
+ 22 +
+
+ 1 +
+
+
        }
+
+
+
+ 23 +
+
+ 1 +
+
+
    }
+
+
+
+ 24 +
+
+ +
+
+

+            
+
+
+ 25 +
+
+ +
+
+
    #[test]
+
+
+
+ 26 +
+
+ 1 +
+
+
    fn xyz_raw() {
+
+
+
+ 27 +
+
+ 1 +
+
+
        // A simple constraints model, manually written using FFI functions.
+
+
+
+ 28 +
+
+ 1 +
+
+
        // Testing to see if it does not segfault.
+
+
+
+ 29 +
+
+ 1 +
+
+
        // Results can be manually inspected in the outputted minion logs.
+
+
+
+ 30 +
+
+ 1 +
+
+
        unsafe {
+
+
+
+ 31 +
+
+ 1 +
+
+
            // See https://rust-lang.github.io/rust-bindgen/cpp.html
+
+
+
+ 32 +
+
+ 1 +
+
+
            let options = searchOptions_new();
+
+
+
+ 33 +
+
+ 1 +
+
+
            let args = searchMethod_new();
+
+
+
+ 34 +
+
+ 1 +
+
+
            let instance = instance_new();
+
+
+
+ 35 +
+
+ 1 +
+
+

+            
+
+
+ 36 +
+
+ 1 +
+
+
            let x_str = CString::new("x").expect("bad x");
+
+
+
+ 37 +
+
+ 1 +
+
+
            let y_str = CString::new("y").expect("bad y");
+
+
+
+ 38 +
+
+ 1 +
+
+
            let z_str = CString::new("z").expect("bad z");
+
+
+
+ 39 +
+
+ 1 +
+
+

+            
+
+
+ 40 +
+
+ 1 +
+
+
            newVar_ffi(instance, x_str.as_ptr() as _, VariableType_VAR_BOUND, 1, 3);
+
+
+
+ 41 +
+
+ 1 +
+
+
            newVar_ffi(instance, y_str.as_ptr() as _, VariableType_VAR_BOUND, 2, 4);
+
+
+
+ 42 +
+
+ 1 +
+
+
            newVar_ffi(instance, z_str.as_ptr() as _, VariableType_VAR_BOUND, 1, 5);
+
+
+
+ 43 +
+
+ 1 +
+
+

+            
+
+
+ 44 +
+
+ 1 +
+
+
            let x = getVarByName(instance, x_str.as_ptr() as _);
+
+
+
+ 45 +
+
+ 1 +
+
+
            let y = getVarByName(instance, y_str.as_ptr() as _);
+
+
+
+ 46 +
+
+ 1 +
+
+
            let z = getVarByName(instance, z_str.as_ptr() as _);
+
+
+
+ 47 +
+
+ 1 +
+
+

+            
+
+
+ 48 +
+
+ 1 +
+
+
            // PRINT
+
+
+
+ 49 +
+
+ 1 +
+
+
            printMatrix_addVar(instance, x);
+
+
+
+ 50 +
+
+ 1 +
+
+
            printMatrix_addVar(instance, y);
+
+
+
+ 51 +
+
+ 1 +
+
+
            printMatrix_addVar(instance, z);
+
+
+
+ 52 +
+
+ 1 +
+
+

+            
+
+
+ 53 +
+
+ 1 +
+
+
            // VARORDER
+
+
+
+ 54 +
+
+ 1 +
+
+
            let search_vars = vec_var_new();
+
+
+
+ 55 +
+
+ 1 +
+
+
            vec_var_push_back(search_vars as _, x);
+
+
+
+ 56 +
+
+ 1 +
+
+
            vec_var_push_back(search_vars as _, y);
+
+
+
+ 57 +
+
+ 1 +
+
+
            vec_var_push_back(search_vars as _, z);
+
+
+
+ 58 +
+
+ 1 +
+
+
            let search_order = searchOrder_new(search_vars as _, VarOrderEnum_ORDER_STATIC, false);
+
+
+
+ 59 +
+
+ 1 +
+
+
            instance_addSearchOrder(instance, search_order);
+
+
+
+ 60 +
+
+ 1 +
+
+

+            
+
+
+ 61 +
+
+ 1 +
+
+
            // CONSTRAINTS
+
+
+
+ 62 +
+
+ 1 +
+
+
            let leq = constraint_new(ConstraintType_CT_LEQSUM);
+
+
+
+ 63 +
+
+ 1 +
+
+
            let geq = constraint_new(ConstraintType_CT_GEQSUM);
+
+
+
+ 64 +
+
+ 1 +
+
+
            let ineq = constraint_new(ConstraintType_CT_INEQ);
+
+
+
+ 65 +
+
+ 1 +
+
+

+            
+
+
+ 66 +
+
+ 1 +
+
+
            let rhs_vars = vec_var_new();
+
+
+
+ 67 +
+
+ 1 +
+
+
            vec_var_push_back(rhs_vars, constantAsVar(4));
+
+
+
+ 68 +
+
+ 1 +
+
+

+            
+
+
+ 69 +
+
+ 1 +
+
+
            // leq / geq : [var] [var]
+
+
+
+ 70 +
+
+ 1 +
+
+
            constraint_addList(leq, search_vars as _);
+
+
+
+ 71 +
+
+ 1 +
+
+
            constraint_addList(leq, rhs_vars as _);
+
+
+
+ 72 +
+
+ 1 +
+
+

+            
+
+
+ 73 +
+
+ 1 +
+
+
            constraint_addList(geq, search_vars as _);
+
+
+
+ 74 +
+
+ 1 +
+
+
            constraint_addList(geq, rhs_vars as _);
+
+
+
+ 75 +
+
+ 1 +
+
+

+            
+
+
+ 76 +
+
+ 1 +
+
+
            // ineq: [var] [var] [const]
+
+
+
+ 77 +
+
+ 1 +
+
+
            let x_vec = vec_var_new();
+
+
+
+ 78 +
+
+ 1 +
+
+
            vec_var_push_back(x_vec, x);
+
+
+
+ 79 +
+
+ 1 +
+
+

+            
+
+
+ 80 +
+
+ 1 +
+
+
            let y_vec = vec_var_new();
+
+
+
+ 81 +
+
+ 1 +
+
+
            vec_var_push_back(y_vec, y);
+
+
+
+ 82 +
+
+ 1 +
+
+

+            
+
+
+ 83 +
+
+ 1 +
+
+
            let const_vec = vec_int_new();
+
+
+
+ 84 +
+
+ 1 +
+
+
            vec_int_push_back(const_vec, -1);
+
+
+
+ 85 +
+
+ 1 +
+
+

+            
+
+
+ 86 +
+
+ 1 +
+
+
            constraint_addList(ineq, x_vec as _);
+
+
+
+ 87 +
+
+ 1 +
+
+
            constraint_addList(ineq, y_vec as _);
+
+
+
+ 88 +
+
+ 1 +
+
+
            constraint_addConstantList(ineq, const_vec as _);
+
+
+
+ 89 +
+
+ 1 +
+
+

+            
+
+
+ 90 +
+
+ 1 +
+
+
            instance_addConstraint(instance, leq);
+
+
+
+ 91 +
+
+ 1 +
+
+
            instance_addConstraint(instance, geq);
+
+
+
+ 92 +
+
+ 1 +
+
+
            instance_addConstraint(instance, ineq);
+
+
+
+ 93 +
+
+ 1 +
+
+

+            
+
+
+ 94 +
+
+ 1 +
+
+
            let res = runMinion(options, args, instance, Some(hello_from_rust));
+
+
+
+ 95 +
+
+ 1 +
+
+

+            
+
+
+ 96 +
+
+ 1 +
+
+
            // does it get this far?
+
+
+
+ 97 +
+
+ 1 +
+
+
            assert_eq!(res, 0);
+
+
+
+ 98 +
+
+ +
+
+

+            
+
+
+ 99 +
+
+ +
+
+
            // test if solutions are correct
+
+
+
+ 100 +
+
+ 1 +
+
+
            assert_eq!(X_VAL, 1);
+
+
+
+ 101 +
+
+ 1 +
+
+
            assert_eq!(Y_VAL, 2);
+
+
+
+ 102 +
+
+ 1 +
+
+
            assert_eq!(Z_VAL, 1);
+
+
+
+ 103 +
+
+ +
+
+
        }
+
+
+
+ 104 +
+
+ 1 +
+
+
    }
+
+
+
+ 105 +
+
+ +
+
+
}
+
+
+
+
+
+

Date: 2024-03-30 15:02

+
+
+ + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/index.html new file mode 100644 index 0000000000..1cebb03809 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/index.html @@ -0,0 +1,194 @@ + + + + + Grcov report - solvers/minion/src + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
ast.rs + + 79.41% + + + 79.41% + + 27 / 34 + 23.81%5 / 21
error.rs + + 0% + + + 0% + + 0 / 7 + 0%0 / 18
ffi.rs + + 100% + + + 100% + + 84 / 84 + 100%2 / 2
lib.rs + + 100% + + + 100% + + 73 / 73 + 100%3 / 3
run.rs + + 60.46% + + + 60.46% + + 341 / 564 + 29.27%24 / 82
scoped_ptr.rs + + 100% + + + 100% + + 6 / 6 + 42.86%6 / 14
+
+
+

Date: 2024-03-30 15:02

+
+
+ + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/lib.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/lib.rs.html new file mode 100644 index 0000000000..fe377b163f --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/lib.rs.html @@ -0,0 +1,1897 @@ + + + + + Grcov report - lib.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
//! This crate provides low level Rust bindings to the [Minion](https://github.com/minion/minion)
+
+
+
+ 2 +
+
+ +
+
+
//! constraint solver.
+
+
+
+ 3 +
+
+ +
+
+
//!
+
+
+
+ 4 +
+
+ +
+
+
//! # Examples
+
+
+
+ 5 +
+
+ +
+
+
//!
+
+
+
+ 6 +
+
+ +
+
+
//! Consider the following Minion problem:
+
+
+
+ 7 +
+
+ +
+
+
//!
+
+
+
+ 8 +
+
+ +
+
+
//! ```plaintext
+
+
+
+ 9 +
+
+ +
+
+
//! MINION 3
+
+
+
+ 10 +
+
+ +
+
+
//! **VARIABLES**
+
+
+
+ 11 +
+
+ +
+
+
//! DISCRETE x #
+
+
+
+ 12 +
+
+ +
+
+
//! {1..3}
+
+
+
+ 13 +
+
+ +
+
+
//! DISCRETE y #
+
+
+
+ 14 +
+
+ +
+
+
//! {2..4}
+
+
+
+ 15 +
+
+ +
+
+
//! DISCRETE z #
+
+
+
+ 16 +
+
+ +
+
+
//! {1..5}
+
+
+
+ 17 +
+
+ +
+
+
//! **SEARCH**
+
+
+
+ 18 +
+
+ +
+
+
//! PRINT[[x],[y],[z]]
+
+
+
+ 19 +
+
+ +
+
+
//! VARORDER STATIC [x, y, z]
+
+
+
+ 20 +
+
+ +
+
+
//! **CONSTRAINTS**
+
+
+
+ 21 +
+
+ +
+
+
//! sumleq([x,y,z],4)
+
+
+
+ 22 +
+
+ +
+
+
//! ineq(x, y, -1)
+
+
+
+ 23 +
+
+ +
+
+
//! **EOF**
+
+
+
+ 24 +
+
+ +
+
+
//! ```
+
+
+
+ 25 +
+
+ +
+
+
//!
+
+
+
+ 26 +
+
+ +
+
+
//! This can be solved in Rust like so:
+
+
+
+ 27 +
+
+ +
+
+
//!
+
+
+
+ 28 +
+
+ +
+
+
//! ```
+
+
+
+ 29 +
+
+ 1 +
+
+
//! use minion_rs::ast::*;
+
+
+
+ 30 +
+
+ 1 +
+
+
//! use minion_rs::run_minion;
+
+
+
+ 31 +
+
+ 1 +
+
+
//! use std::collections::HashMap;
+
+
+
+ 32 +
+
+ 1 +
+
+
//! use std::sync::Mutex;
+
+
+
+ 33 +
+
+ 1 +
+
+
//!
+
+
+
+ 34 +
+
+ 1 +
+
+
//! // Get solutions out of Minion.
+
+
+
+ 35 +
+
+ 1 +
+
+
//! // See the documentation for Callback for details.
+
+
+
+ 36 +
+
+ 1 +
+
+
//!
+
+
+
+ 37 +
+
+ 1 +
+
+
//! static ALL_SOLUTIONS: Mutex<Vec<HashMap<VarName,Constant>>>  = Mutex::new(vec![]);
+
+
+
+ 38 +
+
+ 1 +
+
+
//!
+
+
+
+ 39 +
+
+ 1 +
+
+
//! fn callback(solutions: HashMap<VarName,Constant>) -> bool {
+
+
+
+ 40 +
+
+ 1 +
+
+
//!     let mut guard = ALL_SOLUTIONS.lock().unwrap();
+
+
+
+ 41 +
+
+ 1 +
+
+
//!     guard.push(solutions);
+
+
+
+ 42 +
+
+ 1 +
+
+
//!     true
+
+
+
+ 43 +
+
+ 1 +
+
+
//! }
+
+
+
+ 44 +
+
+ 1 +
+
+
//!
+
+
+
+ 45 +
+
+ 1 +
+
+
//! // Build and run the model.
+
+
+
+ 46 +
+
+ 1 +
+
+
//! let mut model = Model::new();
+
+
+
+ 47 +
+
+ 1 +
+
+
//! model
+
+
+
+ 48 +
+
+ 1 +
+
+
//!     .named_variables
+
+
+
+ 49 +
+
+ 1 +
+
+
//!     .add_var("x".to_owned(), VarDomain::Bound(1, 3));
+
+
+
+ 50 +
+
+ 1 +
+
+
//! model
+
+
+
+ 51 +
+
+ 1 +
+
+
//!     .named_variables
+
+
+
+ 52 +
+
+ 1 +
+
+
//!     .add_var("y".to_owned(), VarDomain::Bound(2, 4));
+
+
+
+ 53 +
+
+ 1 +
+
+
//! model
+
+
+
+ 54 +
+
+ 1 +
+
+
//!     .named_variables
+
+
+
+ 55 +
+
+ 1 +
+
+
//!     .add_var("z".to_owned(), VarDomain::Bound(1, 5));
+
+
+
+ 56 +
+
+ 1 +
+
+
//!
+
+
+
+ 57 +
+
+ 1 +
+
+
//! let leq = Constraint::SumLeq(
+
+
+
+ 58 +
+
+ 1 +
+
+
//!     vec![
+
+
+
+ 59 +
+
+ 1 +
+
+
//!         Var::NameRef("x".to_owned()),
+
+
+
+ 60 +
+
+ 1 +
+
+
//!         Var::NameRef("y".to_owned()),
+
+
+
+ 61 +
+
+ 1 +
+
+
//!         Var::NameRef("z".to_owned()),
+
+
+
+ 62 +
+
+ 1 +
+
+
//!     ],
+
+
+
+ 63 +
+
+ 1 +
+
+
//!     Var::ConstantAsVar(4),
+
+
+
+ 64 +
+
+ 1 +
+
+
//! );
+
+
+
+ 65 +
+
+ 1 +
+
+
//!
+
+
+
+ 66 +
+
+ 1 +
+
+
//! let geq = Constraint::SumGeq(
+
+
+
+ 67 +
+
+ 1 +
+
+
//!     vec![
+
+
+
+ 68 +
+
+ 1 +
+
+
//!         Var::NameRef("x".to_owned()),
+
+
+
+ 69 +
+
+ 1 +
+
+
//!         Var::NameRef("y".to_owned()),
+
+
+
+ 70 +
+
+ 1 +
+
+
//!         Var::NameRef("z".to_owned()),
+
+
+
+ 71 +
+
+ 1 +
+
+
//!     ],
+
+
+
+ 72 +
+
+ 1 +
+
+
//!     Var::ConstantAsVar(4),
+
+
+
+ 73 +
+
+ 1 +
+
+
//! );
+
+
+
+ 74 +
+
+ 1 +
+
+
//!
+
+
+
+ 75 +
+
+ 1 +
+
+
//! let ineq = Constraint::Ineq(
+
+
+
+ 76 +
+
+ 1 +
+
+
//!     Var::NameRef("x".to_owned()),
+
+
+
+ 77 +
+
+ 1 +
+
+
//!     Var::NameRef("y".to_owned()),
+
+
+
+ 78 +
+
+ 1 +
+
+
//!     Constant::Integer(-1),
+
+
+
+ 79 +
+
+ 1 +
+
+
//! );
+
+
+
+ 80 +
+
+ 1 +
+
+
//!
+
+
+
+ 81 +
+
+ 1 +
+
+
//! model.constraints.push(leq);
+
+
+
+ 82 +
+
+ 1 +
+
+
//! model.constraints.push(geq);
+
+
+
+ 83 +
+
+ 1 +
+
+
//! model.constraints.push(ineq);
+
+
+
+ 84 +
+
+ 1 +
+
+
//!
+
+
+
+ 85 +
+
+ 1 +
+
+
//! let res = run_minion(model, callback);
+
+
+
+ 86 +
+
+ 1 +
+
+
//! res.expect("Error occurred");
+
+
+
+ 87 +
+
+ 1 +
+
+
//!
+
+
+
+ 88 +
+
+ 1 +
+
+
//! // Get solutions
+
+
+
+ 89 +
+
+ 1 +
+
+
//! let guard = ALL_SOLUTIONS.lock().unwrap();
+
+
+
+ 90 +
+
+ 1 +
+
+
//! let solution_set_1 = &(guard.get(0).unwrap());
+
+
+
+ 91 +
+
+ 1 +
+
+
//!
+
+
+
+ 92 +
+
+ 1 +
+
+
//! let x1 = solution_set_1.get("x").unwrap();
+
+
+
+ 93 +
+
+ 1 +
+
+
//! let y1 = solution_set_1.get("y").unwrap();
+
+
+
+ 94 +
+
+ 1 +
+
+
//! let z1 = solution_set_1.get("z").unwrap();
+
+
+
+ 95 +
+
+ 1 +
+
+
//!
+
+
+
+ 96 +
+
+ 1 +
+
+
//! assert_eq!(guard.len(),1);
+
+
+
+ 97 +
+
+ 1 +
+
+
//! assert_eq!(*x1,Constant::Integer(1));
+
+
+
+ 98 +
+
+ 1 +
+
+
//! assert_eq!(*y1,Constant::Integer(2));
+
+
+
+ 99 +
+
+ 1 +
+
+
//! assert_eq!(*z1,Constant::Integer(1));
+
+
+
+ 100 +
+
+ 1 +
+
+
//! ```
+
+
+
+ 101 +
+
+ 1 +
+
+
//!
+
+
+
+ 102 +
+
+ +
+
+
//! ## `PRINT` and `VARORDER`
+
+
+
+ 103 +
+
+ +
+
+
//!
+
+
+
+ 104 +
+
+ +
+
+
//! These bindings have no replacement for Minion's `PRINT` and `VARORDER` statements - any
+
+
+
+ 105 +
+
+ +
+
+
//! variable given to the model that does not have a constant value is considered a search
+
+
+
+ 106 +
+
+ +
+
+
//! variable. Solutions are returned through the [callback function](Callback) as a `HashMap`.
+
+
+
+ 107 +
+
+ +
+
+

+            
+
+
+ 108 +
+
+ +
+
+
pub use run::*;
+
+
+
+ 109 +
+
+ +
+
+

+            
+
+
+ 110 +
+
+ +
+
+
pub mod error;
+
+
+
+ 111 +
+
+ +
+
+
mod ffi;
+
+
+
+ 112 +
+
+ +
+
+

+            
+
+
+ 113 +
+
+ +
+
+
pub mod ast;
+
+
+
+ 114 +
+
+ +
+
+
mod run;
+
+
+
+ 115 +
+
+ +
+
+

+            
+
+
+ 116 +
+
+ +
+
+
mod scoped_ptr;
+
+
+
+
+
+

Date: 2024-03-30 15:02

+
+
+ + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/run.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/run.rs.html new file mode 100644 index 0000000000..521d5b2cf8 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/run.rs.html @@ -0,0 +1,12217 @@ + + + + + Grcov report - run.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
#![allow(unreachable_patterns)]
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
use std::{
+
+
+
+ 4 +
+
+ +
+
+
    collections::HashMap,
+
+
+
+ 5 +
+
+ +
+
+
    ffi::CString,
+
+
+
+ 6 +
+
+ +
+
+
    sync::Condvar,
+
+
+
+ 7 +
+
+ +
+
+
    sync::{Mutex, MutexGuard},
+
+
+
+ 8 +
+
+ +
+
+
};
+
+
+
+ 9 +
+
+ +
+
+

+            
+
+
+ 10 +
+
+ +
+
+
use anyhow::anyhow;
+
+
+
+ 11 +
+
+ +
+
+

+            
+
+
+ 12 +
+
+ +
+
+
use crate::ffi::{self};
+
+
+
+ 13 +
+
+ +
+
+
use crate::{ast::*, error::*, scoped_ptr::Scoped};
+
+
+
+ 14 +
+
+ +
+
+

+            
+
+
+ 15 +
+
+ +
+
+
/// The callback function used to capture results from Minion as they are generated.
+
+
+
+ 16 +
+
+ +
+
+
///
+
+
+
+ 17 +
+
+ +
+
+
/// This function is called by Minion whenever a solution is found. The input to this function is
+
+
+
+ 18 +
+
+ +
+
+
/// a`HashMap` of all named variables along with their value.
+
+
+
+ 19 +
+
+ +
+
+
///
+
+
+
+ 20 +
+
+ +
+
+
/// Callbacks should return `true` if search is to continue, `false` otherwise.
+
+
+
+ 21 +
+
+ +
+
+
///
+
+
+
+ 22 +
+
+ +
+
+
/// # Examples
+
+
+
+ 23 +
+
+ +
+
+
///
+
+
+
+ 24 +
+
+ +
+
+
/// Consider using a global mutex (or other static variable) to use returned solutions elsewhere.
+
+
+
+ 25 +
+
+ +
+
+
///
+
+
+
+ 26 +
+
+ +
+
+
/// For example:
+
+
+
+ 27 +
+
+ +
+
+
///
+
+
+
+ 28 +
+
+ +
+
+
/// ```
+
+
+
+ 29 +
+
+ 1 +
+
+
///   use minion_rs::ast::*;
+
+
+
+ 30 +
+
+ 1 +
+
+
///   use minion_rs::run_minion;
+
+
+
+ 31 +
+
+ 1 +
+
+
///   use std::{
+
+
+
+ 32 +
+
+ 1 +
+
+
///       collections::HashMap,
+
+
+
+ 33 +
+
+ 1 +
+
+
///       sync::{Mutex, MutexGuard},
+
+
+
+ 34 +
+
+ 1 +
+
+
///   };
+
+
+
+ 35 +
+
+ 1 +
+
+
///
+
+
+
+ 36 +
+
+ 1 +
+
+
///   // More elaborate data-structures are possible, but for sake of example store
+
+
+
+ 37 +
+
+ 1 +
+
+
///   // a vector of solution sets.
+
+
+
+ 38 +
+
+ 1 +
+
+
///   static ALL_SOLUTIONS: Mutex<Vec<HashMap<VarName,Constant>>>  = Mutex::new(vec![]);
+
+
+
+ 39 +
+
+ 1 +
+
+
///   
+
+
+
+ 40 +
+
+ 1 +
+
+
///   fn callback(solutions: HashMap<VarName,Constant>) -> bool {
+
+
+
+ 41 +
+
+ 1 +
+
+
///       let mut guard = ALL_SOLUTIONS.lock().unwrap();
+
+
+
+ 42 +
+
+ 1 +
+
+
///       guard.push(solutions);
+
+
+
+ 43 +
+
+ 1 +
+
+
///       true
+
+
+
+ 44 +
+
+ 1 +
+
+
///   }
+
+
+
+ 45 +
+
+ 1 +
+
+
///    
+
+
+
+ 46 +
+
+ 1 +
+
+
///   // Build and run the model.
+
+
+
+ 47 +
+
+ 1 +
+
+
///   let mut model = Model::new();
+
+
+
+ 48 +
+
+ 1 +
+
+
///
+
+
+
+ 49 +
+
+ 1 +
+
+
///   // ... omitted for brevity ...
+
+
+
+ 50 +
+
+ 1 +
+
+
/// # model
+
+
+
+ 51 +
+
+ 1 +
+
+
/// #     .named_variables
+
+
+
+ 52 +
+
+ 1 +
+
+
/// #     .add_var("x".to_owned(), VarDomain::Bound(1, 3));
+
+
+
+ 53 +
+
+ 1 +
+
+
/// # model
+
+
+
+ 54 +
+
+ 1 +
+
+
/// #     .named_variables
+
+
+
+ 55 +
+
+ 1 +
+
+
/// #     .add_var("y".to_owned(), VarDomain::Bound(2, 4));
+
+
+
+ 56 +
+
+ 1 +
+
+
/// # model
+
+
+
+ 57 +
+
+ 1 +
+
+
/// #     .named_variables
+
+
+
+ 58 +
+
+ 1 +
+
+
/// #     .add_var("z".to_owned(), VarDomain::Bound(1, 5));
+
+
+
+ 59 +
+
+ 1 +
+
+
/// #
+
+
+
+ 60 +
+
+ 1 +
+
+
/// # let leq = Constraint::SumLeq(
+
+
+
+ 61 +
+
+ 1 +
+
+
/// #     vec![
+
+
+
+ 62 +
+
+ 1 +
+
+
/// #         Var::NameRef("x".to_owned()),
+
+
+
+ 63 +
+
+ 1 +
+
+
/// #         Var::NameRef("y".to_owned()),
+
+
+
+ 64 +
+
+ 1 +
+
+
/// #         Var::NameRef("z".to_owned()),
+
+
+
+ 65 +
+
+ 1 +
+
+
/// #     ],
+
+
+
+ 66 +
+
+ 1 +
+
+
/// #     Var::ConstantAsVar(4),
+
+
+
+ 67 +
+
+ 1 +
+
+
/// # );
+
+
+
+ 68 +
+
+ 1 +
+
+
/// #
+
+
+
+ 69 +
+
+ 1 +
+
+
/// # let geq = Constraint::SumGeq(
+
+
+
+ 70 +
+
+ 1 +
+
+
/// #     vec![
+
+
+
+ 71 +
+
+ 1 +
+
+
/// #         Var::NameRef("x".to_owned()),
+
+
+
+ 72 +
+
+ 1 +
+
+
/// #         Var::NameRef("y".to_owned()),
+
+
+
+ 73 +
+
+ 1 +
+
+
/// #         Var::NameRef("z".to_owned()),
+
+
+
+ 74 +
+
+ 1 +
+
+
/// #     ],
+
+
+
+ 75 +
+
+ 1 +
+
+
/// #     Var::ConstantAsVar(4),
+
+
+
+ 76 +
+
+ 1 +
+
+
/// # );
+
+
+
+ 77 +
+
+ 1 +
+
+
/// #
+
+
+
+ 78 +
+
+ 1 +
+
+
/// # let ineq = Constraint::Ineq(
+
+
+
+ 79 +
+
+ 1 +
+
+
/// #     Var::NameRef("x".to_owned()),
+
+
+
+ 80 +
+
+ 1 +
+
+
/// #     Var::NameRef("y".to_owned()),
+
+
+
+ 81 +
+
+ 1 +
+
+
/// #     Constant::Integer(-1),
+
+
+
+ 82 +
+
+ 1 +
+
+
/// # );
+
+
+
+ 83 +
+
+ 1 +
+
+
/// #
+
+
+
+ 84 +
+
+ 1 +
+
+
/// # model.constraints.push(leq);
+
+
+
+ 85 +
+
+ 1 +
+
+
/// # model.constraints.push(geq);
+
+
+
+ 86 +
+
+ 1 +
+
+
/// # model.constraints.push(ineq);
+
+
+
+ 87 +
+
+ 1 +
+
+
///  
+
+
+
+ 88 +
+
+ 1 +
+
+
///   let res = run_minion(model, callback);
+
+
+
+ 89 +
+
+ 1 +
+
+
///   res.expect("Error occurred");
+
+
+
+ 90 +
+
+ 1 +
+
+
///
+
+
+
+ 91 +
+
+ 1 +
+
+
///   // Get solutions
+
+
+
+ 92 +
+
+ 1 +
+
+
///   let guard = ALL_SOLUTIONS.lock().unwrap();
+
+
+
+ 93 +
+
+ 1 +
+
+
///   let solution_set_1 = &(guard.get(0).unwrap());
+
+
+
+ 94 +
+
+ 1 +
+
+
///
+
+
+
+ 95 +
+
+ 1 +
+
+
///   let x1 = solution_set_1.get("x").unwrap();
+
+
+
+ 96 +
+
+ 1 +
+
+
///   let y1 = solution_set_1.get("y").unwrap();
+
+
+
+ 97 +
+
+ 1 +
+
+
///   let z1 = solution_set_1.get("z").unwrap();
+
+
+
+ 98 +
+
+ 1 +
+
+
/// #
+
+
+
+ 99 +
+
+ 1 +
+
+
/// # // TODO: this test would be better with an example with >1 solution.
+
+
+
+ 100 +
+
+ 1 +
+
+
/// # assert_eq!(guard.len(),1);
+
+
+
+ 101 +
+
+ 1 +
+
+
/// # assert_eq!(*x1,Constant::Integer(1));
+
+
+
+ 102 +
+
+ 1 +
+
+
/// # assert_eq!(*y1,Constant::Integer(2));
+
+
+
+ 103 +
+
+ 1 +
+
+
/// # assert_eq!(*z1,Constant::Integer(1));
+
+
+
+ 104 +
+
+ 1 +
+
+
/// ```
+
+
+
+ 105 +
+
+ 1 +
+
+
pub type Callback = fn(solution_set: HashMap<VarName, Constant>) -> bool;
+
+
+
+ 106 +
+
+ +
+
+

+            
+
+
+ 107 +
+
+ +
+
+
// Use globals to pass things between run_minion and the callback function.
+
+
+
+ 108 +
+
+ +
+
+
// Minion is (currently) single threaded anyways so the Mutexs' don't matter.
+
+
+
+ 109 +
+
+ +
+
+

+            
+
+
+ 110 +
+
+ +
+
+
// the current callback function
+
+
+
+ 111 +
+
+ +
+
+
static CALLBACK: Mutex<Option<Callback>> = Mutex::new(None);
+
+
+
+ 112 +
+
+ +
+
+

+            
+
+
+ 113 +
+
+ +
+
+
// the variables we want to return, and their ordering in the print matrix
+
+
+
+ 114 +
+
+ +
+
+
static PRINT_VARS: Mutex<Option<Vec<VarName>>> = Mutex::new(None);
+
+
+
+ 115 +
+
+ +
+
+

+            
+
+
+ 116 +
+
+ +
+
+
static LOCK: (Mutex<bool>, Condvar) = (Mutex::new(false), Condvar::new());
+
+
+
+ 117 +
+
+ +
+
+

+            
+
+
+ 118 +
+
+ +
+
+
#[no_mangle]
+
+
+
+ 119 +
+
+ 912 +
+
+
unsafe extern "C" fn run_callback() -> bool {
+
+
+
+ 120 +
+
+ 912 +
+
+
    // get printvars from static PRINT_VARS if they exist.
+
+
+
+ 121 +
+
+ 912 +
+
+
    // if not, return true and continue search.
+
+
+
+ 122 +
+
+ 912 +
+
+

+            
+
+
+ 123 +
+
+ 912 +
+
+
    // Mutex poisoning is probably panic worthy.
+
+
+
+ 124 +
+
+ 912 +
+
+
    #[allow(clippy::unwrap_used)]
+
+
+
+ 125 +
+
+ 912 +
+
+
    let mut guard: MutexGuard<'_, Option<Vec<VarName>>> = PRINT_VARS.lock().unwrap();
+
+
+
+ 126 +
+
+ 912 +
+
+

+            
+
+
+ 127 +
+
+ 912 +
+
+
    if guard.is_none() {
+
+
+
+ 128 +
+
+ +
+
+
        return true;
+
+
+
+ 129 +
+
+ 912 +
+
+
    }
+
+
+
+ 130 +
+
+ +
+
+

+            
+
+
+ 131 +
+
+ 912 +
+
+
    let print_vars = match &mut *guard {
+
+
+
+ 132 +
+
+ 912 +
+
+
        Some(x) => x,
+
+
+
+ 133 +
+
+ +
+
+
        None => unreachable!(),
+
+
+
+ 134 +
+
+ +
+
+
    };
+
+
+
+ 135 +
+
+ +
+
+

+            
+
+
+ 136 +
+
+ 912 +
+
+
    if print_vars.is_empty() {
+
+
+
+ 137 +
+
+ +
+
+
        return true;
+
+
+
+ 138 +
+
+ 912 +
+
+
    }
+
+
+
+ 139 +
+
+ 912 +
+
+

+            
+
+
+ 140 +
+
+ 912 +
+
+
    // build nice solutions view to be used by callback
+
+
+
+ 141 +
+
+ 912 +
+
+
    let mut solutions: HashMap<VarName, Constant> = HashMap::new();
+
+
+
+ 142 +
+
+ +
+
+

+            
+
+
+ 143 +
+
+ 2508 +
+
+
    for (i, var) in print_vars.iter().enumerate() {
+
+
+
+ 144 +
+
+ 2508 +
+
+
        let solution_int: i32 = ffi::printMatrix_getValue(i as _);
+
+
+
+ 145 +
+
+ 2508 +
+
+
        let solution: Constant = Constant::Integer(solution_int);
+
+
+
+ 146 +
+
+ 2508 +
+
+
        solutions.insert(var.to_string(), solution);
+
+
+
+ 147 +
+
+ 2508 +
+
+
    }
+
+
+
+ 148 +
+
+ +
+
+

+            
+
+
+ 149 +
+
+ +
+
+
    #[allow(clippy::unwrap_used)]
+
+
+
+ 150 +
+
+ 912 +
+
+
    match *CALLBACK.lock().unwrap() {
+
+
+
+ 151 +
+
+ +
+
+
        None => true,
+
+
+
+ 152 +
+
+ 912 +
+
+
        Some(func) => func(solutions),
+
+
+
+ 153 +
+
+ +
+
+
    }
+
+
+
+ 154 +
+
+ 912 +
+
+
}
+
+
+
+ 155 +
+
+ +
+
+

+            
+
+
+ 156 +
+
+ +
+
+
/// Run Minion on the given [Model].
+
+
+
+ 157 +
+
+ +
+
+
///
+
+
+
+ 158 +
+
+ +
+
+
/// The given [callback](Callback) is ran whenever a new solution set is found.
+
+
+
+ 159 +
+
+ +
+
+

+            
+
+
+ 160 +
+
+ +
+
+
// Turn it into a warning for this function, cant unwarn it directly above callback wierdness
+
+
+
+ 161 +
+
+ +
+
+
#[allow(clippy::unwrap_used)]
+
+
+
+ 162 +
+
+ 285 +
+
+
pub fn run_minion(model: Model, callback: Callback) -> Result<(), MinionError> {
+
+
+
+ 163 +
+
+ 285 +
+
+
    // Mutex poisoning is probably panic worthy.
+
+
+
+ 164 +
+
+ 285 +
+
+
    *CALLBACK.lock().unwrap() = Some(callback);
+
+
+
+ 165 +
+
+ 285 +
+
+

+            
+
+
+ 166 +
+
+ 285 +
+
+
    let (lock, condvar) = &LOCK;
+
+
+
+ 167 +
+
+ 285 +
+
+
    let mut _lock_guard = condvar
+
+
+
+ 168 +
+
+ 285 +
+
+
        .wait_while(lock.lock().unwrap(), |locked| *locked)
+
+
+
+ 169 +
+
+ 285 +
+
+
        .unwrap();
+
+
+
+ 170 +
+
+ 285 +
+
+

+            
+
+
+ 171 +
+
+ 285 +
+
+
    *_lock_guard = true;
+
+
+
+ 172 +
+
+ 285 +
+
+

+            
+
+
+ 173 +
+
+ 285 +
+
+
    unsafe {
+
+
+
+ 174 +
+
+ 285 +
+
+
        // TODO: something better than a manual spinlock
+
+
+
+ 175 +
+
+ 285 +
+
+
        let search_opts = ffi::searchOptions_new();
+
+
+
+ 176 +
+
+ 285 +
+
+
        let search_method = ffi::searchMethod_new();
+
+
+
+ 177 +
+
+ 285 +
+
+
        let search_instance = ffi::instance_new();
+
+
+
+ 178 +
+
+ 285 +
+
+

+            
+
+
+ 179 +
+
+ 285 +
+
+
        convert_model_to_raw(search_instance, &model)?;
+
+
+
+ 180 +
+
+ +
+
+

+            
+
+
+ 181 +
+
+ 285 +
+
+
        let res = ffi::runMinion(
+
+
+
+ 182 +
+
+ 285 +
+
+
            search_opts,
+
+
+
+ 183 +
+
+ 285 +
+
+
            search_method,
+
+
+
+ 184 +
+
+ 285 +
+
+
            search_instance,
+
+
+
+ 185 +
+
+ 285 +
+
+
            Some(run_callback),
+
+
+
+ 186 +
+
+ 285 +
+
+
        );
+
+
+
+ 187 +
+
+ 285 +
+
+

+            
+
+
+ 188 +
+
+ 285 +
+
+
        ffi::searchMethod_free(search_method);
+
+
+
+ 189 +
+
+ 285 +
+
+
        ffi::searchOptions_free(search_opts);
+
+
+
+ 190 +
+
+ 285 +
+
+
        ffi::instance_free(search_instance);
+
+
+
+ 191 +
+
+ 285 +
+
+

+            
+
+
+ 192 +
+
+ 285 +
+
+
        *_lock_guard = false;
+
+
+
+ 193 +
+
+ 285 +
+
+
        std::mem::drop(_lock_guard);
+
+
+
+ 194 +
+
+ 285 +
+
+

+            
+
+
+ 195 +
+
+ 285 +
+
+
        condvar.notify_one();
+
+
+
+ 196 +
+
+ 285 +
+
+

+            
+
+
+ 197 +
+
+ 285 +
+
+
        match res {
+
+
+
+ 198 +
+
+ 285 +
+
+
            0 => Ok(()),
+
+
+
+ 199 +
+
+ +
+
+
            x => Err(MinionError::from(RuntimeError::from(x))),
+
+
+
+ 200 +
+
+ +
+
+
        }
+
+
+
+ 201 +
+
+ +
+
+
    }
+
+
+
+ 202 +
+
+ 285 +
+
+
}
+
+
+
+ 203 +
+
+ +
+
+

+            
+
+
+ 204 +
+
+ 285 +
+
+
unsafe fn convert_model_to_raw(
+
+
+
+ 205 +
+
+ 285 +
+
+
    instance: *mut ffi::ProbSpec_CSPInstance,
+
+
+
+ 206 +
+
+ 285 +
+
+
    model: &Model,
+
+
+
+ 207 +
+
+ 285 +
+
+
) -> Result<(), MinionError> {
+
+
+
+ 208 +
+
+ 285 +
+
+
    /*******************************/
+
+
+
+ 209 +
+
+ 285 +
+
+
    /*        Add variables        */
+
+
+
+ 210 +
+
+ 285 +
+
+
    /*******************************/
+
+
+
+ 211 +
+
+ 285 +
+
+

+            
+
+
+ 212 +
+
+ 285 +
+
+
    /*
+
+
+
+ 213 +
+
+ 285 +
+
+
     * Add variables to:
+
+
+
+ 214 +
+
+ 285 +
+
+
     * 1. symbol table
+
+
+
+ 215 +
+
+ 285 +
+
+
     * 2. print matrix
+
+
+
+ 216 +
+
+ 285 +
+
+
     * 3. search vars
+
+
+
+ 217 +
+
+ 285 +
+
+
     *
+
+
+
+ 218 +
+
+ 285 +
+
+
     * These are all done in the order saved in the SymbolTable.
+
+
+
+ 219 +
+
+ 285 +
+
+
     */
+
+
+
+ 220 +
+
+ 285 +
+
+

+            
+
+
+ 221 +
+
+ 285 +
+
+
    let search_vars = Scoped::new(ffi::vec_var_new(), |x| ffi::vec_var_free(x as _));
+
+
+
+ 222 +
+
+ 285 +
+
+

+            
+
+
+ 223 +
+
+ 285 +
+
+
    // store variables and the order they will be returned inside rust for later use.
+
+
+
+ 224 +
+
+ 285 +
+
+
    #[allow(clippy::unwrap_used)]
+
+
+
+ 225 +
+
+ 285 +
+
+
    let mut print_vars_guard = PRINT_VARS.lock().unwrap();
+
+
+
+ 226 +
+
+ 285 +
+
+
    *print_vars_guard = Some(vec![]);
+
+
+
+ 227 +
+
+ +
+
+

+            
+
+
+ 228 +
+
+ 760 +
+
+
    for var_name in model.named_variables.get_variable_order() {
+
+
+
+ 229 +
+
+ 760 +
+
+
        let c_str = CString::new(var_name.clone()).map_err(|_| {
+
+
+
+ 230 +
+
+ +
+
+
            anyhow!(
+
+
+
+ 231 +
+
+ +
+
+
                "Variable name {:?} contains a null character.",
+
+
+
+ 232 +
+
+ +
+
+
                var_name.clone()
+
+
+
+ 233 +
+
+ +
+
+
            )
+
+
+
+ 234 +
+
+ 760 +
+
+
        })?;
+
+
+
+ 235 +
+
+ +
+
+

+            
+
+
+ 236 +
+
+ 760 +
+
+
        let vartype = model
+
+
+
+ 237 +
+
+ 760 +
+
+
            .named_variables
+
+
+
+ 238 +
+
+ 760 +
+
+
            .get_vartype(var_name.clone())
+
+
+
+ 239 +
+
+ 760 +
+
+
            .ok_or(anyhow!("Could not get var type for {:?}", var_name.clone()))?;
+
+
+
+ 240 +
+
+ +
+
+

+            
+
+
+ 241 +
+
+ 760 +
+
+
        let (vartype_raw, domain_low, domain_high) = match vartype {
+
+
+
+ 242 +
+
+ 570 +
+
+
            VarDomain::Bound(a, b) => Ok((ffi::VariableType_VAR_BOUND, a, b)),
+
+
+
+ 243 +
+
+ 190 +
+
+
            VarDomain::Bool => Ok((ffi::VariableType_VAR_BOOL, 0, 1)), // TODO: will this work?
+
+
+
+ 244 +
+
+ +
+
+
            x => Err(MinionError::NotImplemented(format!("{:?}", x))),
+
+
+
+ 245 +
+
+ +
+
+
        }?;
+
+
+
+ 246 +
+
+ +
+
+

+            
+
+
+ 247 +
+
+ 760 +
+
+
        ffi::newVar_ffi(
+
+
+
+ 248 +
+
+ 760 +
+
+
            instance,
+
+
+
+ 249 +
+
+ 760 +
+
+
            c_str.as_ptr() as _,
+
+
+
+ 250 +
+
+ 760 +
+
+
            vartype_raw,
+
+
+
+ 251 +
+
+ 760 +
+
+
            domain_low,
+
+
+
+ 252 +
+
+ 760 +
+
+
            domain_high,
+
+
+
+ 253 +
+
+ 760 +
+
+
        );
+
+
+
+ 254 +
+
+ 760 +
+
+

+            
+
+
+ 255 +
+
+ 760 +
+
+
        let var = ffi::getVarByName(instance, c_str.as_ptr() as _);
+
+
+
+ 256 +
+
+ 760 +
+
+

+            
+
+
+ 257 +
+
+ 760 +
+
+
        ffi::printMatrix_addVar(instance, var);
+
+
+
+ 258 +
+
+ 760 +
+
+

+            
+
+
+ 259 +
+
+ 760 +
+
+
        // add to the print vars stored in rust so to remember
+
+
+
+ 260 +
+
+ 760 +
+
+
        // the order for callback function.
+
+
+
+ 261 +
+
+ 760 +
+
+

+            
+
+
+ 262 +
+
+ 760 +
+
+
        #[allow(clippy::unwrap_used)]
+
+
+
+ 263 +
+
+ 760 +
+
+
        (*print_vars_guard).as_mut().unwrap().push(var_name.clone());
+
+
+
+ 264 +
+
+ 760 +
+
+

+            
+
+
+ 265 +
+
+ 760 +
+
+
        ffi::vec_var_push_back(search_vars.ptr, var);
+
+
+
+ 266 +
+
+ +
+
+
    }
+
+
+
+ 267 +
+
+ +
+
+

+            
+
+
+ 268 +
+
+ 285 +
+
+
    let search_order = Scoped::new(
+
+
+
+ 269 +
+
+ 285 +
+
+
        ffi::searchOrder_new(search_vars.ptr, ffi::VarOrderEnum_ORDER_STATIC, false),
+
+
+
+ 270 +
+
+ 285 +
+
+
        |x| ffi::searchOrder_free(x as _),
+
+
+
+ 271 +
+
+ 285 +
+
+
    );
+
+
+
+ 272 +
+
+ 285 +
+
+

+            
+
+
+ 273 +
+
+ 285 +
+
+
    ffi::instance_addSearchOrder(instance, search_order.ptr);
+
+
+
+ 274 +
+
+ +
+
+

+            
+
+
+ 275 +
+
+ +
+
+
    /*********************************/
+
+
+
+ 276 +
+
+ +
+
+
    /*        Add constraints        */
+
+
+
+ 277 +
+
+ +
+
+
    /*********************************/
+
+
+
+ 278 +
+
+ +
+
+

+            
+
+
+ 279 +
+
+ 1273 +
+
+
    for constraint in &model.constraints {
+
+
+
+ 280 +
+
+ +
+
+
        // 1. get constraint type and create C++ constraint object
+
+
+
+ 281 +
+
+ +
+
+
        // 2. run through arguments and add them to the constraint
+
+
+
+ 282 +
+
+ +
+
+
        // 3. add constraint to instance
+
+
+
+ 283 +
+
+ +
+
+

+            
+
+
+ 284 +
+
+ 988 +
+
+
        let constraint_type = get_constraint_type(constraint)?;
+
+
+
+ 285 +
+
+ 988 +
+
+
        let raw_constraint = Scoped::new(ffi::constraint_new(constraint_type), |x| {
+
+
+
+ 286 +
+
+ 988 +
+
+
            ffi::constraint_free(x as _)
+
+
+
+ 287 +
+
+ 988 +
+
+
        });
+
+
+
+ 288 +
+
+ 988 +
+
+

+            
+
+
+ 289 +
+
+ 988 +
+
+
        constraint_add_args(instance, raw_constraint.ptr, constraint)?;
+
+
+
+ 290 +
+
+ 988 +
+
+
        ffi::instance_addConstraint(instance, raw_constraint.ptr);
+
+
+
+ 291 +
+
+ +
+
+
    }
+
+
+
+ 292 +
+
+ +
+
+

+            
+
+
+ 293 +
+
+ 285 +
+
+
    Ok(())
+
+
+
+ 294 +
+
+ 285 +
+
+
}
+
+
+
+ 295 +
+
+ +
+
+

+            
+
+
+ 296 +
+
+ 1805 +
+
+
unsafe fn get_constraint_type(constraint: &Constraint) -> Result<u32, MinionError> {
+
+
+
+ 297 +
+
+ 1805 +
+
+
    match constraint {
+
+
+
+ 298 +
+
+ 76 +
+
+
        Constraint::SumGeq(_, _) => Ok(ffi::ConstraintType_CT_GEQSUM),
+
+
+
+ 299 +
+
+ 95 +
+
+
        Constraint::SumLeq(_, _) => Ok(ffi::ConstraintType_CT_LEQSUM),
+
+
+
+ 300 +
+
+ 1140 +
+
+
        Constraint::Ineq(_, _, _) => Ok(ffi::ConstraintType_CT_INEQ),
+
+
+
+ 301 +
+
+ +
+
+
        Constraint::Eq(_, _) => Ok(ffi::ConstraintType_CT_EQ),
+
+
+
+ 302 +
+
+ +
+
+
        Constraint::Difference(_, _) => Ok(ffi::ConstraintType_CT_DIFFERENCE),
+
+
+
+ 303 +
+
+ +
+
+
        Constraint::Div(_, _) => Ok(ffi::ConstraintType_CT_DIV),
+
+
+
+ 304 +
+
+ +
+
+
        Constraint::DivUndefZero(_, _) => Ok(ffi::ConstraintType_CT_DIV_UNDEFZERO),
+
+
+
+ 305 +
+
+ +
+
+
        Constraint::Modulo(_, _) => Ok(ffi::ConstraintType_CT_MODULO),
+
+
+
+ 306 +
+
+ +
+
+
        Constraint::ModuloUndefZero(_, _) => Ok(ffi::ConstraintType_CT_MODULO_UNDEFZERO),
+
+
+
+ 307 +
+
+ +
+
+
        Constraint::Pow(_, _) => Ok(ffi::ConstraintType_CT_POW),
+
+
+
+ 308 +
+
+ +
+
+
        Constraint::Product(_, _) => Ok(ffi::ConstraintType_CT_PRODUCT2),
+
+
+
+ 309 +
+
+ +
+
+
        Constraint::WeightedSumGeq(_, _, _) => Ok(ffi::ConstraintType_CT_WEIGHTGEQSUM),
+
+
+
+ 310 +
+
+ +
+
+
        Constraint::WeightedSumLeq(_, _, _) => Ok(ffi::ConstraintType_CT_WEIGHTLEQSUM),
+
+
+
+ 311 +
+
+ +
+
+
        Constraint::CheckAssign(_) => Ok(ffi::ConstraintType_CT_CHECK_ASSIGN),
+
+
+
+ 312 +
+
+ +
+
+
        Constraint::CheckGsa(_) => Ok(ffi::ConstraintType_CT_CHECK_GSA),
+
+
+
+ 313 +
+
+ +
+
+
        Constraint::ForwardChecking(_) => Ok(ffi::ConstraintType_CT_FORWARD_CHECKING),
+
+
+
+ 314 +
+
+ +
+
+
        Constraint::Reify(_, _) => Ok(ffi::ConstraintType_CT_REIFY),
+
+
+
+ 315 +
+
+ 19 +
+
+
        Constraint::ReifyImply(_, _) => Ok(ffi::ConstraintType_CT_REIFYIMPLY),
+
+
+
+ 316 +
+
+ +
+
+
        Constraint::ReifyImplyQuick(_, _) => Ok(ffi::ConstraintType_CT_REIFYIMPLY_QUICK),
+
+
+
+ 317 +
+
+ +
+
+
        Constraint::WatchedAnd(_) => Ok(ffi::ConstraintType_CT_WATCHED_NEW_AND),
+
+
+
+ 318 +
+
+ 399 +
+
+
        Constraint::WatchedOr(_) => Ok(ffi::ConstraintType_CT_WATCHED_NEW_OR),
+
+
+
+ 319 +
+
+ +
+
+
        Constraint::GacAllDiff(_) => Ok(ffi::ConstraintType_CT_GACALLDIFF),
+
+
+
+ 320 +
+
+ 38 +
+
+
        Constraint::AllDiff(_) => Ok(ffi::ConstraintType_CT_ALLDIFF),
+
+
+
+ 321 +
+
+ +
+
+
        Constraint::AllDiffMatrix(_, _) => Ok(ffi::ConstraintType_CT_ALLDIFFMATRIX),
+
+
+
+ 322 +
+
+ +
+
+
        Constraint::WatchSumGeq(_, _) => Ok(ffi::ConstraintType_CT_WATCHED_GEQSUM),
+
+
+
+ 323 +
+
+ +
+
+
        Constraint::WatchSumLeq(_, _) => Ok(ffi::ConstraintType_CT_WATCHED_LEQSUM),
+
+
+
+ 324 +
+
+ +
+
+
        Constraint::OccurrenceGeq(_, _, _) => Ok(ffi::ConstraintType_CT_GEQ_OCCURRENCE),
+
+
+
+ 325 +
+
+ +
+
+
        Constraint::OccurrenceLeq(_, _, _) => Ok(ffi::ConstraintType_CT_LEQ_OCCURRENCE),
+
+
+
+ 326 +
+
+ +
+
+
        Constraint::Occurrence(_, _, _) => Ok(ffi::ConstraintType_CT_OCCURRENCE),
+
+
+
+ 327 +
+
+ +
+
+
        Constraint::LitSumGeq(_, _, _) => Ok(ffi::ConstraintType_CT_WATCHED_LITSUM),
+
+
+
+ 328 +
+
+ +
+
+
        Constraint::Gcc(_, _, _) => Ok(ffi::ConstraintType_CT_GCC),
+
+
+
+ 329 +
+
+ +
+
+
        Constraint::GccWeak(_, _, _) => Ok(ffi::ConstraintType_CT_GCCWEAK),
+
+
+
+ 330 +
+
+ +
+
+
        Constraint::LexLeqRv(_, _) => Ok(ffi::ConstraintType_CT_GACLEXLEQ),
+
+
+
+ 331 +
+
+ +
+
+
        Constraint::LexLeq(_, _) => Ok(ffi::ConstraintType_CT_LEXLEQ),
+
+
+
+ 332 +
+
+ +
+
+
        Constraint::LexLess(_, _) => Ok(ffi::ConstraintType_CT_LEXLESS),
+
+
+
+ 333 +
+
+ +
+
+
        Constraint::LexLeqQuick(_, _) => Ok(ffi::ConstraintType_CT_QUICK_LEXLEQ),
+
+
+
+ 334 +
+
+ +
+
+
        Constraint::LexLessQuick(_, _) => Ok(ffi::ConstraintType_CT_QUICK_LEXLEQ),
+
+
+
+ 335 +
+
+ +
+
+
        Constraint::WatchVecNeq(_, _) => Ok(ffi::ConstraintType_CT_WATCHED_VECNEQ),
+
+
+
+ 336 +
+
+ +
+
+
        Constraint::WatchVecExistsLess(_, _) => Ok(ffi::ConstraintType_CT_WATCHED_VEC_OR_LESS),
+
+
+
+ 337 +
+
+ +
+
+
        Constraint::Hamming(_, _, _) => Ok(ffi::ConstraintType_CT_WATCHED_HAMMING),
+
+
+
+ 338 +
+
+ +
+
+
        Constraint::NotHamming(_, _, _) => Ok(ffi::ConstraintType_CT_WATCHED_NOT_HAMMING),
+
+
+
+ 339 +
+
+ +
+
+
        Constraint::FrameUpdate(_, _, _, _, _) => Ok(ffi::ConstraintType_CT_FRAMEUPDATE),
+
+
+
+ 340 +
+
+ +
+
+
        Constraint::NegativeTable(_, _) => Ok(ffi::ConstraintType_CT_WATCHED_NEGATIVE_TABLE),
+
+
+
+ 341 +
+
+ +
+
+
        Constraint::Table(_, _) => Ok(ffi::ConstraintType_CT_WATCHED_TABLE),
+
+
+
+ 342 +
+
+ +
+
+
        Constraint::GacSchema(_, _) => Ok(ffi::ConstraintType_CT_GACSCHEMA),
+
+
+
+ 343 +
+
+ +
+
+
        Constraint::LightTable(_, _) => Ok(ffi::ConstraintType_CT_LIGHTTABLE),
+
+
+
+ 344 +
+
+ +
+
+
        Constraint::Mddc(_, _) => Ok(ffi::ConstraintType_CT_MDDC),
+
+
+
+ 345 +
+
+ +
+
+
        Constraint::NegativeMddc(_, _) => Ok(ffi::ConstraintType_CT_NEGATIVEMDDC),
+
+
+
+ 346 +
+
+ +
+
+
        Constraint::Str2Plus(_, _) => Ok(ffi::ConstraintType_CT_STR),
+
+
+
+ 347 +
+
+ +
+
+
        Constraint::Max(_, _) => Ok(ffi::ConstraintType_CT_MAX),
+
+
+
+ 348 +
+
+ +
+
+
        Constraint::Min(_, _) => Ok(ffi::ConstraintType_CT_MIN),
+
+
+
+ 349 +
+
+ +
+
+
        Constraint::NvalueGeq(_, _) => Ok(ffi::ConstraintType_CT_GEQNVALUE),
+
+
+
+ 350 +
+
+ +
+
+
        Constraint::NvalueLeq(_, _) => Ok(ffi::ConstraintType_CT_LEQNVALUE),
+
+
+
+ 351 +
+
+ +
+
+
        Constraint::Element(_, _, _) => Ok(ffi::ConstraintType_CT_ELEMENT),
+
+
+
+ 352 +
+
+ +
+
+
        Constraint::ElementOne(_, _, _) => Ok(ffi::ConstraintType_CT_ELEMENT_ONE),
+
+
+
+ 353 +
+
+ +
+
+
        Constraint::ElementUndefZero(_, _, _) => Ok(ffi::ConstraintType_CT_ELEMENT_UNDEFZERO),
+
+
+
+ 354 +
+
+ +
+
+
        Constraint::WatchElement(_, _, _) => Ok(ffi::ConstraintType_CT_WATCHED_ELEMENT),
+
+
+
+ 355 +
+
+ +
+
+
        Constraint::WatchElementOne(_, _, _) => Ok(ffi::ConstraintType_CT_WATCHED_ELEMENT_ONE),
+
+
+
+ 356 +
+
+ +
+
+
        Constraint::WatchElementOneUndefZero(_, _, _) => {
+
+
+
+ 357 +
+
+ +
+
+
            Ok(ffi::ConstraintType_CT_WATCHED_ELEMENT_ONE_UNDEFZERO)
+
+
+
+ 358 +
+
+ +
+
+
        }
+
+
+
+ 359 +
+
+ +
+
+
        Constraint::WatchElementUndefZero(_, _, _) => {
+
+
+
+ 360 +
+
+ +
+
+
            Ok(ffi::ConstraintType_CT_WATCHED_ELEMENT_UNDEFZERO)
+
+
+
+ 361 +
+
+ +
+
+
        }
+
+
+
+ 362 +
+
+ +
+
+
        Constraint::WLiteral(_, _) => Ok(ffi::ConstraintType_CT_WATCHED_LIT),
+
+
+
+ 363 +
+
+ +
+
+
        Constraint::WNotLiteral(_, _) => Ok(ffi::ConstraintType_CT_WATCHED_NOTLIT),
+
+
+
+ 364 +
+
+ +
+
+
        Constraint::WInIntervalSet(_, _) => Ok(ffi::ConstraintType_CT_WATCHED_ININTERVALSET),
+
+
+
+ 365 +
+
+ +
+
+
        Constraint::WInRange(_, _) => Ok(ffi::ConstraintType_CT_WATCHED_INRANGE),
+
+
+
+ 366 +
+
+ 38 +
+
+
        Constraint::WInset(_, _) => Ok(ffi::ConstraintType_CT_WATCHED_INSET),
+
+
+
+ 367 +
+
+ +
+
+
        Constraint::WNotInRange(_, _) => Ok(ffi::ConstraintType_CT_WATCHED_NOT_INRANGE),
+
+
+
+ 368 +
+
+ +
+
+
        Constraint::WNotInset(_, _) => Ok(ffi::ConstraintType_CT_WATCHED_NOT_INSET),
+
+
+
+ 369 +
+
+ +
+
+
        Constraint::Abs(_, _) => Ok(ffi::ConstraintType_CT_ABS),
+
+
+
+ 370 +
+
+ +
+
+
        Constraint::DisEq(_, _) => Ok(ffi::ConstraintType_CT_DISEQ),
+
+
+
+ 371 +
+
+ +
+
+
        Constraint::MinusEq(_, _) => Ok(ffi::ConstraintType_CT_MINUSEQ),
+
+
+
+ 372 +
+
+ +
+
+
        Constraint::GacEq(_, _) => Ok(ffi::ConstraintType_CT_GACEQ),
+
+
+
+ 373 +
+
+ +
+
+
        Constraint::WatchLess(_, _) => Ok(ffi::ConstraintType_CT_WATCHED_LESS),
+
+
+
+ 374 +
+
+ +
+
+
        Constraint::WatchNeq(_, _) => Ok(ffi::ConstraintType_CT_WATCHED_NEQ),
+
+
+
+ 375 +
+
+ +
+
+

+            
+
+
+ 376 +
+
+ +
+
+
        #[allow(unreachable_patterns)]
+
+
+
+ 377 +
+
+ +
+
+
        x => Err(MinionError::NotImplemented(format!(
+
+
+
+ 378 +
+
+ +
+
+
            "Constraint not implemented {:?}",
+
+
+
+ 379 +
+
+ +
+
+
            x,
+
+
+
+ 380 +
+
+ +
+
+
        ))),
+
+
+
+ 381 +
+
+ +
+
+
    }
+
+
+
+ 382 +
+
+ 1805 +
+
+
}
+
+
+
+ 383 +
+
+ +
+
+

+            
+
+
+ 384 +
+
+ 1805 +
+
+
unsafe fn constraint_add_args(
+
+
+
+ 385 +
+
+ 1805 +
+
+
    i: *mut ffi::ProbSpec_CSPInstance,
+
+
+
+ 386 +
+
+ 1805 +
+
+
    r_constr: *mut ffi::ProbSpec_ConstraintBlob,
+
+
+
+ 387 +
+
+ 1805 +
+
+
    constr: &Constraint,
+
+
+
+ 388 +
+
+ 1805 +
+
+
) -> Result<(), MinionError> {
+
+
+
+ 389 +
+
+ 1805 +
+
+
    match constr {
+
+
+
+ 390 +
+
+ 76 +
+
+
        Constraint::SumGeq(lhs_vars, rhs_var) => {
+
+
+
+ 391 +
+
+ 76 +
+
+
            read_list(i, r_constr, lhs_vars)?;
+
+
+
+ 392 +
+
+ 76 +
+
+
            read_var(i, r_constr, rhs_var)?;
+
+
+
+ 393 +
+
+ 76 +
+
+
            Ok(())
+
+
+
+ 394 +
+
+ +
+
+
        }
+
+
+
+ 395 +
+
+ 95 +
+
+
        Constraint::SumLeq(lhs_vars, rhs_var) => {
+
+
+
+ 396 +
+
+ 95 +
+
+
            read_list(i, r_constr, lhs_vars)?;
+
+
+
+ 397 +
+
+ 95 +
+
+
            read_var(i, r_constr, rhs_var)?;
+
+
+
+ 398 +
+
+ 95 +
+
+
            Ok(())
+
+
+
+ 399 +
+
+ +
+
+
        }
+
+
+
+ 400 +
+
+ 1140 +
+
+
        Constraint::Ineq(var1, var2, c) => {
+
+
+
+ 401 +
+
+ 1140 +
+
+
            read_var(i, r_constr, var1)?;
+
+
+
+ 402 +
+
+ 1140 +
+
+
            read_var(i, r_constr, var2)?;
+
+
+
+ 403 +
+
+ 1140 +
+
+
            read_constant(r_constr, c)?;
+
+
+
+ 404 +
+
+ 1140 +
+
+
            Ok(())
+
+
+
+ 405 +
+
+ +
+
+
        }
+
+
+
+ 406 +
+
+ +
+
+
        Constraint::Eq(var1, var2) => {
+
+
+
+ 407 +
+
+ +
+
+
            read_var(i, r_constr, var1)?;
+
+
+
+ 408 +
+
+ +
+
+
            read_var(i, r_constr, var2)?;
+
+
+
+ 409 +
+
+ +
+
+
            Ok(())
+
+
+
+ 410 +
+
+ +
+
+
        }
+
+
+
+ 411 +
+
+ +
+
+
        Constraint::Difference((a, b), c) => {
+
+
+
+ 412 +
+
+ +
+
+
            read_2_vars(i, r_constr, a, b)?;
+
+
+
+ 413 +
+
+ +
+
+
            read_var(i, r_constr, c)?;
+
+
+
+ 414 +
+
+ +
+
+
            Ok(())
+
+
+
+ 415 +
+
+ +
+
+
        }
+
+
+
+ 416 +
+
+ +
+
+
        Constraint::Div((a, b), c) => {
+
+
+
+ 417 +
+
+ +
+
+
            read_2_vars(i, r_constr, a, b)?;
+
+
+
+ 418 +
+
+ +
+
+
            read_var(i, r_constr, c)?;
+
+
+
+ 419 +
+
+ +
+
+
            Ok(())
+
+
+
+ 420 +
+
+ +
+
+
        }
+
+
+
+ 421 +
+
+ +
+
+
        Constraint::DivUndefZero((a, b), c) => {
+
+
+
+ 422 +
+
+ +
+
+
            read_2_vars(i, r_constr, a, b)?;
+
+
+
+ 423 +
+
+ +
+
+
            read_var(i, r_constr, c)?;
+
+
+
+ 424 +
+
+ +
+
+
            Ok(())
+
+
+
+ 425 +
+
+ +
+
+
        }
+
+
+
+ 426 +
+
+ +
+
+
        Constraint::Modulo((a, b), c) => {
+
+
+
+ 427 +
+
+ +
+
+
            read_2_vars(i, r_constr, a, b)?;
+
+
+
+ 428 +
+
+ +
+
+
            read_var(i, r_constr, c)?;
+
+
+
+ 429 +
+
+ +
+
+
            Ok(())
+
+
+
+ 430 +
+
+ +
+
+
        }
+
+
+
+ 431 +
+
+ +
+
+
        Constraint::ModuloUndefZero((a, b), c) => {
+
+
+
+ 432 +
+
+ +
+
+
            read_2_vars(i, r_constr, a, b)?;
+
+
+
+ 433 +
+
+ +
+
+
            read_var(i, r_constr, c)?;
+
+
+
+ 434 +
+
+ +
+
+
            Ok(())
+
+
+
+ 435 +
+
+ +
+
+
        }
+
+
+
+ 436 +
+
+ +
+
+
        Constraint::Pow((a, b), c) => {
+
+
+
+ 437 +
+
+ +
+
+
            read_2_vars(i, r_constr, a, b)?;
+
+
+
+ 438 +
+
+ +
+
+
            read_var(i, r_constr, c)?;
+
+
+
+ 439 +
+
+ +
+
+
            Ok(())
+
+
+
+ 440 +
+
+ +
+
+
        }
+
+
+
+ 441 +
+
+ +
+
+
        Constraint::Product((a, b), c) => {
+
+
+
+ 442 +
+
+ +
+
+
            read_2_vars(i, r_constr, a, b)?;
+
+
+
+ 443 +
+
+ +
+
+
            read_var(i, r_constr, c)?;
+
+
+
+ 444 +
+
+ +
+
+
            Ok(())
+
+
+
+ 445 +
+
+ +
+
+
        }
+
+
+
+ 446 +
+
+ +
+
+
        Constraint::WeightedSumGeq(a, b, c) => {
+
+
+
+ 447 +
+
+ +
+
+
            read_constant_list(r_constr, a)?;
+
+
+
+ 448 +
+
+ +
+
+
            read_list(i, r_constr, b)?;
+
+
+
+ 449 +
+
+ +
+
+
            read_var(i, r_constr, c)?;
+
+
+
+ 450 +
+
+ +
+
+
            Ok(())
+
+
+
+ 451 +
+
+ +
+
+
        }
+
+
+
+ 452 +
+
+ +
+
+
        Constraint::WeightedSumLeq(a, b, c) => {
+
+
+
+ 453 +
+
+ +
+
+
            read_constant_list(r_constr, a)?;
+
+
+
+ 454 +
+
+ +
+
+
            read_list(i, r_constr, b)?;
+
+
+
+ 455 +
+
+ +
+
+
            read_var(i, r_constr, c)?;
+
+
+
+ 456 +
+
+ +
+
+
            Ok(())
+
+
+
+ 457 +
+
+ +
+
+
        }
+
+
+
+ 458 +
+
+ +
+
+
        Constraint::CheckAssign(a) => {
+
+
+
+ 459 +
+
+ +
+
+
            read_constraint(i, r_constr, (**a).clone())?;
+
+
+
+ 460 +
+
+ +
+
+
            Ok(())
+
+
+
+ 461 +
+
+ +
+
+
        }
+
+
+
+ 462 +
+
+ +
+
+
        Constraint::CheckGsa(a) => {
+
+
+
+ 463 +
+
+ +
+
+
            read_constraint(i, r_constr, (**a).clone())?;
+
+
+
+ 464 +
+
+ +
+
+
            Ok(())
+
+
+
+ 465 +
+
+ +
+
+
        }
+
+
+
+ 466 +
+
+ +
+
+
        Constraint::ForwardChecking(a) => {
+
+
+
+ 467 +
+
+ +
+
+
            read_constraint(i, r_constr, (**a).clone())?;
+
+
+
+ 468 +
+
+ +
+
+
            Ok(())
+
+
+
+ 469 +
+
+ +
+
+
        }
+
+
+
+ 470 +
+
+ +
+
+
        Constraint::Reify(a, b) => {
+
+
+
+ 471 +
+
+ +
+
+
            read_constraint(i, r_constr, (**a).clone())?;
+
+
+
+ 472 +
+
+ +
+
+
            read_var(i, r_constr, b)?;
+
+
+
+ 473 +
+
+ +
+
+
            Ok(())
+
+
+
+ 474 +
+
+ +
+
+
        }
+
+
+
+ 475 +
+
+ 19 +
+
+
        Constraint::ReifyImply(a, b) => {
+
+
+
+ 476 +
+
+ 19 +
+
+
            read_constraint(i, r_constr, (**a).clone())?;
+
+
+
+ 477 +
+
+ 19 +
+
+
            read_var(i, r_constr, b)?;
+
+
+
+ 478 +
+
+ 19 +
+
+
            Ok(())
+
+
+
+ 479 +
+
+ +
+
+
        }
+
+
+
+ 480 +
+
+ +
+
+
        Constraint::ReifyImplyQuick(a, b) => {
+
+
+
+ 481 +
+
+ +
+
+
            read_constraint(i, r_constr, (**a).clone())?;
+
+
+
+ 482 +
+
+ +
+
+
            read_var(i, r_constr, b)?;
+
+
+
+ 483 +
+
+ +
+
+
            Ok(())
+
+
+
+ 484 +
+
+ +
+
+
        }
+
+
+
+ 485 +
+
+ +
+
+
        Constraint::WatchedAnd(a) => {
+
+
+
+ 486 +
+
+ +
+
+
            read_constraint_list(i, r_constr, a)?;
+
+
+
+ 487 +
+
+ +
+
+
            Ok(())
+
+
+
+ 488 +
+
+ +
+
+
        }
+
+
+
+ 489 +
+
+ 399 +
+
+
        Constraint::WatchedOr(a) => {
+
+
+
+ 490 +
+
+ 399 +
+
+
            read_constraint_list(i, r_constr, a)?;
+
+
+
+ 491 +
+
+ 399 +
+
+
            Ok(())
+
+
+
+ 492 +
+
+ +
+
+
        }
+
+
+
+ 493 +
+
+ +
+
+
        Constraint::GacAllDiff(a) => {
+
+
+
+ 494 +
+
+ +
+
+
            read_list(i, r_constr, a)?;
+
+
+
+ 495 +
+
+ +
+
+
            Ok(())
+
+
+
+ 496 +
+
+ +
+
+
        }
+
+
+
+ 497 +
+
+ 38 +
+
+
        Constraint::AllDiff(a) => {
+
+
+
+ 498 +
+
+ 38 +
+
+
            read_list(i, r_constr, a)?;
+
+
+
+ 499 +
+
+ 38 +
+
+
            Ok(())
+
+
+
+ 500 +
+
+ +
+
+
        }
+
+
+
+ 501 +
+
+ +
+
+
        Constraint::AllDiffMatrix(a, b) => {
+
+
+
+ 502 +
+
+ +
+
+
            read_list(i, r_constr, a)?;
+
+
+
+ 503 +
+
+ +
+
+
            read_constant(r_constr, b)?;
+
+
+
+ 504 +
+
+ +
+
+
            Ok(())
+
+
+
+ 505 +
+
+ +
+
+
        }
+
+
+
+ 506 +
+
+ +
+
+
        Constraint::WatchSumGeq(a, b) => {
+
+
+
+ 507 +
+
+ +
+
+
            read_list(i, r_constr, a)?;
+
+
+
+ 508 +
+
+ +
+
+
            read_constant(r_constr, b)?;
+
+
+
+ 509 +
+
+ +
+
+
            Ok(())
+
+
+
+ 510 +
+
+ +
+
+
        }
+
+
+
+ 511 +
+
+ +
+
+
        Constraint::WatchSumLeq(a, b) => {
+
+
+
+ 512 +
+
+ +
+
+
            read_list(i, r_constr, a)?;
+
+
+
+ 513 +
+
+ +
+
+
            read_constant(r_constr, b)?;
+
+
+
+ 514 +
+
+ +
+
+
            Ok(())
+
+
+
+ 515 +
+
+ +
+
+
        }
+
+
+
+ 516 +
+
+ +
+
+
        Constraint::OccurrenceGeq(a, b, c) => {
+
+
+
+ 517 +
+
+ +
+
+
            read_list(i, r_constr, a)?;
+
+
+
+ 518 +
+
+ +
+
+
            read_constant(r_constr, b)?;
+
+
+
+ 519 +
+
+ +
+
+
            read_constant(r_constr, c)?;
+
+
+
+ 520 +
+
+ +
+
+
            Ok(())
+
+
+
+ 521 +
+
+ +
+
+
        }
+
+
+
+ 522 +
+
+ +
+
+
        Constraint::OccurrenceLeq(a, b, c) => {
+
+
+
+ 523 +
+
+ +
+
+
            read_list(i, r_constr, a)?;
+
+
+
+ 524 +
+
+ +
+
+
            read_constant(r_constr, b)?;
+
+
+
+ 525 +
+
+ +
+
+
            read_constant(r_constr, c)?;
+
+
+
+ 526 +
+
+ +
+
+
            Ok(())
+
+
+
+ 527 +
+
+ +
+
+
        }
+
+
+
+ 528 +
+
+ +
+
+
        Constraint::Occurrence(a, b, c) => {
+
+
+
+ 529 +
+
+ +
+
+
            read_list(i, r_constr, a)?;
+
+
+
+ 530 +
+
+ +
+
+
            read_constant(r_constr, b)?;
+
+
+
+ 531 +
+
+ +
+
+
            read_var(i, r_constr, c)?;
+
+
+
+ 532 +
+
+ +
+
+
            Ok(())
+
+
+
+ 533 +
+
+ +
+
+
        }
+
+
+
+ 534 +
+
+ +
+
+
        //Constraint::LitSumGeq(_, _, _) => todo!(),
+
+
+
+ 535 +
+
+ +
+
+
        //Constraint::Gcc(_, _, _) => todo!(),
+
+
+
+ 536 +
+
+ +
+
+
        //Constraint::GccWeak(_, _, _) => todo!(),
+
+
+
+ 537 +
+
+ +
+
+
        //Constraint::LexLeqRv(_, _) => todo!(),
+
+
+
+ 538 +
+
+ +
+
+
        //Constraint::LexLeq(_, _) => todo!(),
+
+
+
+ 539 +
+
+ +
+
+
        //Constraint::LexLess(_, _) => todo!(),
+
+
+
+ 540 +
+
+ +
+
+
        //Constraint::LexLeqQuick(_, _) => todo!(),
+
+
+
+ 541 +
+
+ +
+
+
        //Constraint::LexLessQuick(_, _) => todo!(),
+
+
+
+ 542 +
+
+ +
+
+
        //Constraint::WatchVecNeq(_, _) => todo!(),
+
+
+
+ 543 +
+
+ +
+
+
        //Constraint::WatchVecExistsLess(_, _) => todo!(),
+
+
+
+ 544 +
+
+ +
+
+
        //Constraint::Hamming(_, _, _) => todo!(),
+
+
+
+ 545 +
+
+ +
+
+
        //Constraint::NotHamming(_, _, _) => todo!(),
+
+
+
+ 546 +
+
+ +
+
+
        //Constraint::FrameUpdate(_, _, _, _, _) => todo!(),
+
+
+
+ 547 +
+
+ +
+
+
        //Constraint::NegativeTable(_, _) => todo!(),
+
+
+
+ 548 +
+
+ +
+
+
        //Constraint::Table(_, _) => todo!(),
+
+
+
+ 549 +
+
+ +
+
+
        //Constraint::GacSchema(_, _) => todo!(),
+
+
+
+ 550 +
+
+ +
+
+
        //Constraint::LightTable(_, _) => todo!(),
+
+
+
+ 551 +
+
+ +
+
+
        //Constraint::Mddc(_, _) => todo!(),
+
+
+
+ 552 +
+
+ +
+
+
        //Constraint::NegativeMddc(_, _) => todo!(),
+
+
+
+ 553 +
+
+ +
+
+
        //Constraint::Str2Plus(_, _) => todo!(),
+
+
+
+ 554 +
+
+ +
+
+
        //Constraint::Max(_, _) => todo!(),
+
+
+
+ 555 +
+
+ +
+
+
        //Constraint::Min(_, _) => todo!(),
+
+
+
+ 556 +
+
+ +
+
+
        //Constraint::NvalueGeq(_, _) => todo!(),
+
+
+
+ 557 +
+
+ +
+
+
        //Constraint::NvalueLeq(_, _) => todo!(),
+
+
+
+ 558 +
+
+ +
+
+
        //Constraint::Element(_, _, _) => todo!(),
+
+
+
+ 559 +
+
+ +
+
+
        //Constraint::ElementOne(_, _, _) => todo!(),
+
+
+
+ 560 +
+
+ +
+
+
        //Constraint::ElementUndefZero(_, _, _) => todo!(),
+
+
+
+ 561 +
+
+ +
+
+
        //Constraint::WatchElement(_, _, _) => todo!(),
+
+
+
+ 562 +
+
+ +
+
+
        //Constraint::WatchElementOne(_, _, _) => todo!(),
+
+
+
+ 563 +
+
+ +
+
+
        //Constraint::WatchElementOneUndefZero(_, _, _) => todo!(),
+
+
+
+ 564 +
+
+ +
+
+
        //Constraint::WatchElementUndefZero(_, _, _) => todo!(),
+
+
+
+ 565 +
+
+ +
+
+
        //Constraint::WLiteral(_, _) => todo!(),
+
+
+
+ 566 +
+
+ +
+
+
        //Constraint::WNotLiteral(_, _) => todo!(),
+
+
+
+ 567 +
+
+ +
+
+
        //Constraint::WInIntervalSet(_, _) => todo!(),
+
+
+
+ 568 +
+
+ +
+
+
        //Constraint::WInRange(_, _) => todo!(),
+
+
+
+ 569 +
+
+ 38 +
+
+
        Constraint::WInset(a, b) => {
+
+
+
+ 570 +
+
+ 38 +
+
+
            read_var(i, r_constr, a)?;
+
+
+
+ 571 +
+
+ 38 +
+
+
            read_constant_list(r_constr, b)?;
+
+
+
+ 572 +
+
+ 38 +
+
+
            Ok(())
+
+
+
+ 573 +
+
+ +
+
+
        }
+
+
+
+ 574 +
+
+ +
+
+
        //Constraint::WNotInRange(_, _) => todo!(),
+
+
+
+ 575 +
+
+ +
+
+
        //Constraint::WNotInset(_, _) => todo!(),
+
+
+
+ 576 +
+
+ +
+
+
        //Constraint::Abs(_, _) => todo!(),
+
+
+
+ 577 +
+
+ +
+
+
        //Constraint::DisEq(_, _) => todo!(),
+
+
+
+ 578 +
+
+ +
+
+
        //Constraint::MinusEq(_, _) => todo!(),
+
+
+
+ 579 +
+
+ +
+
+
        //Constraint::GacEq(_, _) => todo!(),
+
+
+
+ 580 +
+
+ +
+
+
        //Constraint::WatchLess(_, _) => todo!(),
+
+
+
+ 581 +
+
+ +
+
+
        // TODO: ensure that this is a bool?
+
+
+
+ 582 +
+
+ +
+
+
        Constraint::WatchNeq(a, b) => {
+
+
+
+ 583 +
+
+ +
+
+
            read_var(i, r_constr, a)?;
+
+
+
+ 584 +
+
+ +
+
+
            read_var(i, r_constr, b)?;
+
+
+
+ 585 +
+
+ +
+
+
            Ok(())
+
+
+
+ 586 +
+
+ +
+
+
        }
+
+
+
+ 587 +
+
+ +
+
+
        #[allow(unreachable_patterns)]
+
+
+
+ 588 +
+
+ +
+
+
        x => Err(MinionError::NotImplemented(format!("{:?}", x))),
+
+
+
+ 589 +
+
+ +
+
+
    }
+
+
+
+ 590 +
+
+ 1805 +
+
+
}
+
+
+
+ 591 +
+
+ +
+
+

+            
+
+
+ 592 +
+
+ +
+
+
// DO NOT call manually - this assumes that all needed vars are already in the symbol table.
+
+
+
+ 593 +
+
+ +
+
+
// TODO not happy with this just assuming the name is in the symbol table
+
+
+
+ 594 +
+
+ 209 +
+
+
unsafe fn read_list(
+
+
+
+ 595 +
+
+ 209 +
+
+
    instance: *mut ffi::ProbSpec_CSPInstance,
+
+
+
+ 596 +
+
+ 209 +
+
+
    raw_constraint: *mut ffi::ProbSpec_ConstraintBlob,
+
+
+
+ 597 +
+
+ 209 +
+
+
    vars: &Vec<Var>,
+
+
+
+ 598 +
+
+ 209 +
+
+
) -> Result<(), MinionError> {
+
+
+
+ 599 +
+
+ 209 +
+
+
    let raw_vars = Scoped::new(ffi::vec_var_new(), |x| ffi::vec_var_free(x as _));
+
+
+
+ 600 +
+
+ 798 +
+
+
    for var in vars {
+
+
+
+ 601 +
+
+ 589 +
+
+
        let raw_var = match var {
+
+
+
+ 602 +
+
+ 589 +
+
+
            Var::NameRef(name) => {
+
+
+
+ 603 +
+
+ 589 +
+
+
                let c_str = CString::new(name.clone()).map_err(|_| {
+
+
+
+ 604 +
+
+ +
+
+
                    anyhow!(
+
+
+
+ 605 +
+
+ +
+
+
                        "Variable name {:?} contains a null character.",
+
+
+
+ 606 +
+
+ +
+
+
                        name.clone()
+
+
+
+ 607 +
+
+ +
+
+
                    )
+
+
+
+ 608 +
+
+ 589 +
+
+
                })?;
+
+
+
+ 609 +
+
+ 589 +
+
+
                ffi::getVarByName(instance, c_str.as_ptr() as _)
+
+
+
+ 610 +
+
+ +
+
+
            }
+
+
+
+ 611 +
+
+ +
+
+
            Var::ConstantAsVar(n) => ffi::constantAsVar(*n),
+
+
+
+ 612 +
+
+ +
+
+
        };
+
+
+
+ 613 +
+
+ +
+
+

+            
+
+
+ 614 +
+
+ 589 +
+
+
        ffi::vec_var_push_back(raw_vars.ptr, raw_var);
+
+
+
+ 615 +
+
+ +
+
+
    }
+
+
+
+ 616 +
+
+ +
+
+

+            
+
+
+ 617 +
+
+ 209 +
+
+
    ffi::constraint_addList(raw_constraint, raw_vars.ptr);
+
+
+
+ 618 +
+
+ 209 +
+
+

+            
+
+
+ 619 +
+
+ 209 +
+
+
    Ok(())
+
+
+
+ 620 +
+
+ 209 +
+
+
}
+
+
+
+ 621 +
+
+ +
+
+

+            
+
+
+ 622 +
+
+ 2508 +
+
+
unsafe fn read_var(
+
+
+
+ 623 +
+
+ 2508 +
+
+
    instance: *mut ffi::ProbSpec_CSPInstance,
+
+
+
+ 624 +
+
+ 2508 +
+
+
    raw_constraint: *mut ffi::ProbSpec_ConstraintBlob,
+
+
+
+ 625 +
+
+ 2508 +
+
+
    var: &Var,
+
+
+
+ 626 +
+
+ 2508 +
+
+
) -> Result<(), MinionError> {
+
+
+
+ 627 +
+
+ 2508 +
+
+
    let raw_vars = Scoped::new(ffi::vec_var_new(), |x| ffi::vec_var_free(x as _));
+
+
+
+ 628 +
+
+ 2508 +
+
+
    let raw_var = match var {
+
+
+
+ 629 +
+
+ 2242 +
+
+
        Var::NameRef(name) => {
+
+
+
+ 630 +
+
+ 2242 +
+
+
            let c_str = CString::new(name.clone()).map_err(|_| {
+
+
+
+ 631 +
+
+ +
+
+
                anyhow!(
+
+
+
+ 632 +
+
+ +
+
+
                    "Variable name {:?} contains a null character.",
+
+
+
+ 633 +
+
+ +
+
+
                    name.clone()
+
+
+
+ 634 +
+
+ +
+
+
                )
+
+
+
+ 635 +
+
+ 2242 +
+
+
            })?;
+
+
+
+ 636 +
+
+ 2242 +
+
+
            ffi::getVarByName(instance, c_str.as_ptr() as _)
+
+
+
+ 637 +
+
+ +
+
+
        }
+
+
+
+ 638 +
+
+ 266 +
+
+
        Var::ConstantAsVar(n) => ffi::constantAsVar(*n),
+
+
+
+ 639 +
+
+ +
+
+
    };
+
+
+
+ 640 +
+
+ +
+
+

+            
+
+
+ 641 +
+
+ 2508 +
+
+
    ffi::vec_var_push_back(raw_vars.ptr, raw_var);
+
+
+
+ 642 +
+
+ 2508 +
+
+
    ffi::constraint_addList(raw_constraint, raw_vars.ptr);
+
+
+
+ 643 +
+
+ 2508 +
+
+

+            
+
+
+ 644 +
+
+ 2508 +
+
+
    Ok(())
+
+
+
+ 645 +
+
+ 2508 +
+
+
}
+
+
+
+ 646 +
+
+ +
+
+

+            
+
+
+ 647 +
+
+ +
+
+
unsafe fn read_2_vars(
+
+
+
+ 648 +
+
+ +
+
+
    instance: *mut ffi::ProbSpec_CSPInstance,
+
+
+
+ 649 +
+
+ +
+
+
    raw_constraint: *mut ffi::ProbSpec_ConstraintBlob,
+
+
+
+ 650 +
+
+ +
+
+
    var1: &Var,
+
+
+
+ 651 +
+
+ +
+
+
    var2: &Var,
+
+
+
+ 652 +
+
+ +
+
+
) -> Result<(), MinionError> {
+
+
+
+ 653 +
+
+ +
+
+
    let mut raw_var = match var1 {
+
+
+
+ 654 +
+
+ +
+
+
        Var::NameRef(name) => {
+
+
+
+ 655 +
+
+ +
+
+
            let c_str = CString::new(name.clone()).map_err(|_| {
+
+
+
+ 656 +
+
+ +
+
+
                anyhow!(
+
+
+
+ 657 +
+
+ +
+
+
                    "Variable name {:?} contains a null character.",
+
+
+
+ 658 +
+
+ +
+
+
                    name.clone()
+
+
+
+ 659 +
+
+ +
+
+
                )
+
+
+
+ 660 +
+
+ +
+
+
            })?;
+
+
+
+ 661 +
+
+ +
+
+
            ffi::getVarByName(instance, c_str.as_ptr() as _)
+
+
+
+ 662 +
+
+ +
+
+
        }
+
+
+
+ 663 +
+
+ +
+
+
        Var::ConstantAsVar(n) => ffi::constantAsVar(*n),
+
+
+
+ 664 +
+
+ +
+
+
    };
+
+
+
+ 665 +
+
+ +
+
+
    let mut raw_var2 = match var2 {
+
+
+
+ 666 +
+
+ +
+
+
        Var::NameRef(name) => {
+
+
+
+ 667 +
+
+ +
+
+
            let c_str = CString::new(name.clone()).map_err(|_| {
+
+
+
+ 668 +
+
+ +
+
+
                anyhow!(
+
+
+
+ 669 +
+
+ +
+
+
                    "Variable name {:?} contains a null character.",
+
+
+
+ 670 +
+
+ +
+
+
                    name.clone()
+
+
+
+ 671 +
+
+ +
+
+
                )
+
+
+
+ 672 +
+
+ +
+
+
            })?;
+
+
+
+ 673 +
+
+ +
+
+
            ffi::getVarByName(instance, c_str.as_ptr() as _)
+
+
+
+ 674 +
+
+ +
+
+
        }
+
+
+
+ 675 +
+
+ +
+
+
        Var::ConstantAsVar(n) => ffi::constantAsVar(*n),
+
+
+
+ 676 +
+
+ +
+
+
    };
+
+
+
+ 677 +
+
+ +
+
+
    // todo: does this move or copy? I am confus!
+
+
+
+ 678 +
+
+ +
+
+
    // TODO need to mkae the semantics of move vs copy / ownership clear in libminion!!
+
+
+
+ 679 +
+
+ +
+
+
    // This shouldve leaked everywhere by now but i think libminion copies stuff??
+
+
+
+ 680 +
+
+ +
+
+
    ffi::constraint_addTwoVars(raw_constraint, &mut raw_var, &mut raw_var2);
+
+
+
+ 681 +
+
+ +
+
+
    Ok(())
+
+
+
+ 682 +
+
+ +
+
+
}
+
+
+
+ 683 +
+
+ +
+
+

+            
+
+
+ 684 +
+
+ 1140 +
+
+
unsafe fn read_constant(
+
+
+
+ 685 +
+
+ 1140 +
+
+
    raw_constraint: *mut ffi::ProbSpec_ConstraintBlob,
+
+
+
+ 686 +
+
+ 1140 +
+
+
    constant: &Constant,
+
+
+
+ 687 +
+
+ 1140 +
+
+
) -> Result<(), MinionError> {
+
+
+
+ 688 +
+
+ 1140 +
+
+
    let val: i32 = match constant {
+
+
+
+ 689 +
+
+ 1140 +
+
+
        Constant::Integer(n) => Ok(*n),
+
+
+
+ 690 +
+
+ +
+
+
        Constant::Bool(true) => Ok(1),
+
+
+
+ 691 +
+
+ +
+
+
        Constant::Bool(false) => Ok(0),
+
+
+
+ 692 +
+
+ +
+
+
        x => Err(MinionError::NotImplemented(format!("{:?}", x))),
+
+
+
+ 693 +
+
+ +
+
+
    }?;
+
+
+
+ 694 +
+
+ +
+
+

+            
+
+
+ 695 +
+
+ 1140 +
+
+
    ffi::constraint_addConstant(raw_constraint, val);
+
+
+
+ 696 +
+
+ 1140 +
+
+

+            
+
+
+ 697 +
+
+ 1140 +
+
+
    Ok(())
+
+
+
+ 698 +
+
+ 1140 +
+
+
}
+
+
+
+ 699 +
+
+ +
+
+

+            
+
+
+ 700 +
+
+ 38 +
+
+
unsafe fn read_constant_list(
+
+
+
+ 701 +
+
+ 38 +
+
+
    raw_constraint: *mut ffi::ProbSpec_ConstraintBlob,
+
+
+
+ 702 +
+
+ 38 +
+
+
    constants: &[Constant],
+
+
+
+ 703 +
+
+ 38 +
+
+
) -> Result<(), MinionError> {
+
+
+
+ 704 +
+
+ 38 +
+
+
    let raw_consts = Scoped::new(ffi::vec_int_new(), |x| ffi::vec_var_free(x as _));
+
+
+
+ 705 +
+
+ +
+
+

+            
+
+
+ 706 +
+
+ 38 +
+
+
    for constant in constants.iter() {
+
+
+
+ 707 +
+
+ 38 +
+
+
        let val = match constant {
+
+
+
+ 708 +
+
+ +
+
+
            Constant::Integer(n) => Ok(*n),
+
+
+
+ 709 +
+
+ 19 +
+
+
            Constant::Bool(true) => Ok(1),
+
+
+
+ 710 +
+
+ 19 +
+
+
            Constant::Bool(false) => Ok(0),
+
+
+
+ 711 +
+
+ +
+
+
            #[allow(unreachable_patterns)] // TODO: can there be other types?
+
+
+
+ 712 +
+
+ +
+
+
            x => Err(MinionError::NotImplemented(format!("{:?}", x))),
+
+
+
+ 713 +
+
+ +
+
+
        }?;
+
+
+
+ 714 +
+
+ +
+
+

+            
+
+
+ 715 +
+
+ 38 +
+
+
        ffi::vec_int_push_back(raw_consts.ptr, val);
+
+
+
+ 716 +
+
+ +
+
+
    }
+
+
+
+ 717 +
+
+ +
+
+

+            
+
+
+ 718 +
+
+ 38 +
+
+
    ffi::constraint_addConstantList(raw_constraint, raw_consts.ptr);
+
+
+
+ 719 +
+
+ 38 +
+
+
    Ok(())
+
+
+
+ 720 +
+
+ 38 +
+
+
}
+
+
+
+ 721 +
+
+ +
+
+

+            
+
+
+ 722 +
+
+ +
+
+
//TODO: check if the inner constraint is listed in the model or not?
+
+
+
+ 723 +
+
+ +
+
+
//Does this matter?
+
+
+
+ 724 +
+
+ +
+
+
// TODO: type-check inner constraints vars and tuples and so on?
+
+
+
+ 725 +
+
+ 19 +
+
+
unsafe fn read_constraint(
+
+
+
+ 726 +
+
+ 19 +
+
+
    instance: *mut ffi::ProbSpec_CSPInstance,
+
+
+
+ 727 +
+
+ 19 +
+
+
    raw_constraint: *mut ffi::ProbSpec_ConstraintBlob,
+
+
+
+ 728 +
+
+ 19 +
+
+
    inner_constraint: Constraint,
+
+
+
+ 729 +
+
+ 19 +
+
+
) -> Result<(), MinionError> {
+
+
+
+ 730 +
+
+ 19 +
+
+
    let constraint_type = get_constraint_type(&inner_constraint)?;
+
+
+
+ 731 +
+
+ 19 +
+
+
    let raw_inner_constraint = Scoped::new(ffi::constraint_new(constraint_type), |x| {
+
+
+
+ 732 +
+
+ 19 +
+
+
        ffi::constraint_free(x as _)
+
+
+
+ 733 +
+
+ 19 +
+
+
    });
+
+
+
+ 734 +
+
+ 19 +
+
+

+            
+
+
+ 735 +
+
+ 19 +
+
+
    constraint_add_args(instance, raw_inner_constraint.ptr, &inner_constraint)?;
+
+
+
+ 736 +
+
+ +
+
+

+            
+
+
+ 737 +
+
+ 19 +
+
+
    ffi::constraint_addConstraint(raw_constraint, raw_inner_constraint.ptr);
+
+
+
+ 738 +
+
+ 19 +
+
+
    Ok(())
+
+
+
+ 739 +
+
+ 19 +
+
+
}
+
+
+
+ 740 +
+
+ +
+
+

+            
+
+
+ 741 +
+
+ 399 +
+
+
unsafe fn read_constraint_list(
+
+
+
+ 742 +
+
+ 399 +
+
+
    instance: *mut ffi::ProbSpec_CSPInstance,
+
+
+
+ 743 +
+
+ 399 +
+
+
    raw_constraint: *mut ffi::ProbSpec_ConstraintBlob,
+
+
+
+ 744 +
+
+ 399 +
+
+
    inner_constraints: &[Constraint],
+
+
+
+ 745 +
+
+ 399 +
+
+
) -> Result<(), MinionError> {
+
+
+
+ 746 +
+
+ 399 +
+
+
    let raw_inners = Scoped::new(ffi::vec_constraints_new(), |x| {
+
+
+
+ 747 +
+
+ 399 +
+
+
        ffi::vec_constraints_free(x as _)
+
+
+
+ 748 +
+
+ 399 +
+
+
    });
+
+
+
+ 749 +
+
+ 798 +
+
+
    for inner_constraint in inner_constraints.iter() {
+
+
+
+ 750 +
+
+ 798 +
+
+
        let constraint_type = get_constraint_type(inner_constraint)?;
+
+
+
+ 751 +
+
+ 798 +
+
+
        let raw_inner_constraint = Scoped::new(ffi::constraint_new(constraint_type), |x| {
+
+
+
+ 752 +
+
+ 798 +
+
+
            ffi::constraint_free(x as _)
+
+
+
+ 753 +
+
+ 798 +
+
+
        });
+
+
+
+ 754 +
+
+ 798 +
+
+

+            
+
+
+ 755 +
+
+ 798 +
+
+
        constraint_add_args(instance, raw_inner_constraint.ptr, inner_constraint)?;
+
+
+
+ 756 +
+
+ 798 +
+
+
        ffi::vec_constraints_push_back(raw_inners.ptr, raw_inner_constraint.ptr);
+
+
+
+ 757 +
+
+ +
+
+
    }
+
+
+
+ 758 +
+
+ +
+
+

+            
+
+
+ 759 +
+
+ 399 +
+
+
    ffi::constraint_addConstraintList(raw_constraint, raw_inners.ptr);
+
+
+
+ 760 +
+
+ 399 +
+
+
    Ok(())
+
+
+
+ 761 +
+
+ 399 +
+
+
}
+
+
+
+
+
+

Date: 2024-03-30 15:02

+
+
+ + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/scoped_ptr.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/scoped_ptr.rs.html new file mode 100644 index 0000000000..c6dbdd70f5 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/src/scoped_ptr.rs.html @@ -0,0 +1,473 @@ + + + + + Grcov report - scoped_ptr.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
/// A light scoped wrapper over a raw *mut pointer.
+
+
+
+ 2 +
+
+ +
+
+
///
+
+
+
+ 3 +
+
+ +
+
+
/// Implements destruction of the pointer when it goes out of scope, but provides no other
+
+
+
+ 4 +
+
+ +
+
+
/// guarantees.
+
+
+
+ 5 +
+
+ +
+
+
#[non_exhaustive]
+
+
+
+ 6 +
+
+ +
+
+
pub struct Scoped<T> {
+
+
+
+ 7 +
+
+ +
+
+
    pub ptr: *mut T,
+
+
+
+ 8 +
+
+ +
+
+
    destructor: fn(*mut T),
+
+
+
+ 9 +
+
+ +
+
+
}
+
+
+
+ 10 +
+
+ +
+
+

+            
+
+
+ 11 +
+
+ +
+
+
// Could use
+
+
+
+ 12 +
+
+ +
+
+
// https://doc.rust-lang.org/std/alloc/trait.Allocator.html with box (in nightly only)
+
+
+
+ 13 +
+
+ +
+
+
// or
+
+
+
+ 14 +
+
+ +
+
+
// https://docs.rs/scopeguard/latest/scopeguard/
+
+
+
+ 15 +
+
+ +
+
+
// instead
+
+
+
+ 16 +
+
+ +
+
+
impl<T> Scoped<T> {
+
+
+
+ 17 +
+
+ 5529 +
+
+
    pub unsafe fn new(ptr: *mut T, destructor: fn(*mut T)) -> Scoped<T> {
+
+
+
+ 18 +
+
+ 5529 +
+
+
        Scoped { ptr, destructor }
+
+
+
+ 19 +
+
+ 5529 +
+
+
    }
+
+
+
+ 20 +
+
+ +
+
+
}
+
+
+
+ 21 +
+
+ +
+
+

+            
+
+
+ 22 +
+
+ +
+
+
// https://doc.rust-lang.org/nomicon/destructors.html
+
+
+
+ 23 +
+
+ +
+
+
impl<T> Drop for Scoped<T> {
+
+
+
+ 24 +
+
+ 5529 +
+
+
    fn drop(&mut self) {
+
+
+
+ 25 +
+
+ 5529 +
+
+
        (self.destructor)(self.ptr);
+
+
+
+ 26 +
+
+ 5529 +
+
+
    }
+
+
+
+ 27 +
+
+ +
+
+
}
+
+
+
+
+
+

Date: 2024-03-30 15:02

+
+
+ + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/tests/index.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/tests/index.html new file mode 100644 index 0000000000..b22b50e944 --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/tests/index.html @@ -0,0 +1,74 @@ + + + + + Grcov report - solvers/minion/tests + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctions
test_watchedor_reifyimply_1.rs + + 100% + + + 100% + + 31 / 31 + 100%2 / 2
+
+
+

Date: 2024-03-30 15:02

+
+
+ + diff --git a/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/tests/test_watchedor_reifyimply_1.rs.html b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/tests/test_watchedor_reifyimply_1.rs.html new file mode 100644 index 0000000000..3279f40c6d --- /dev/null +++ b/coverage/86f194547b9068fafb5ae7ae6dfb328383c11062/solvers/minion/tests/test_watchedor_reifyimply_1.rs.html @@ -0,0 +1,1033 @@ + + + + + Grcov report - test_watchedor_reifyimply_1.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
//! based on this minion test file:
+
+
+
+ 2 +
+
+ +
+
+
//! https://github.com/minion/minion/blob/main/test_instances/test_watchedor_reifyimply_1.minion
+
+
+
+ 3 +
+
+ +
+
+
//!
+
+
+
+ 4 +
+
+ +
+
+
//! ```text
+
+
+
+ 5 +
+
+ +
+
+
//! #TEST SOLCOUNT 7
+
+
+
+ 6 +
+
+ +
+
+
//! # Recursive test
+
+
+
+ 7 +
+
+ +
+
+
//! MINION 3
+
+
+
+ 8 +
+
+ +
+
+
//!
+
+
+
+ 9 +
+
+ +
+
+
//! **VARIABLES**
+
+
+
+ 10 +
+
+ +
+
+
//! BOOL a
+
+
+
+ 11 +
+
+ +
+
+
//! BOOL b
+
+
+
+ 12 +
+
+ +
+
+
//! BOOL c
+
+
+
+ 13 +
+
+ +
+
+
//!
+
+
+
+ 14 +
+
+ +
+
+
//! **CONSTRAINTS**
+
+
+
+ 15 +
+
+ +
+
+
//!
+
+
+
+ 16 +
+
+ +
+
+
//! reifyimply(watched-or({w-inset(a,[1]),w-inset(b,[0])}), c)
+
+
+
+ 17 +
+
+ +
+
+
//!
+
+
+
+ 18 +
+
+ +
+
+
//! **EOF**
+
+
+
+ 19 +
+
+ +
+
+
//! ```
+
+
+
+ 20 +
+
+ +
+
+

+            
+
+
+ 21 +
+
+ +
+
+
use std::collections::HashMap;
+
+
+
+ 22 +
+
+ +
+
+
use std::sync::Mutex;
+
+
+
+ 23 +
+
+ +
+
+

+            
+
+
+ 24 +
+
+ +
+
+
use minion_rs::ast::{Constant, Constraint, Model, Var, VarDomain, VarName};
+
+
+
+ 25 +
+
+ +
+
+
use minion_rs::error::MinionError;
+
+
+
+ 26 +
+
+ +
+
+

+            
+
+
+ 27 +
+
+ +
+
+
#[test]
+
+
+
+ 28 +
+
+ +
+
+
#[allow(clippy::panic_in_result_fn)]
+
+
+
+ 29 +
+
+ 1 +
+
+
fn test_watchedor_reifyimply_1() -> Result<(), MinionError> {
+
+
+
+ 30 +
+
+ 1 +
+
+
    let mut model = Model::new();
+
+
+
+ 31 +
+
+ 1 +
+
+
    model
+
+
+
+ 32 +
+
+ 1 +
+
+
        .named_variables
+
+
+
+ 33 +
+
+ 1 +
+
+
        .add_var(String::from("a"), VarDomain::Bool);
+
+
+
+ 34 +
+
+ 1 +
+
+
    model
+
+
+
+ 35 +
+
+ 1 +
+
+
        .named_variables
+
+
+
+ 36 +
+
+ 1 +
+
+
        .add_var(String::from("b"), VarDomain::Bool);
+
+
+
+ 37 +
+
+ 1 +
+
+
    model
+
+
+
+ 38 +
+
+ 1 +
+
+
        .named_variables
+
+
+
+ 39 +
+
+ 1 +
+
+
        .add_var(String::from("c"), VarDomain::Bool);
+
+
+
+ 40 +
+
+ 1 +
+
+

+            
+
+
+ 41 +
+
+ 1 +
+
+
    model.constraints.push(Constraint::ReifyImply(
+
+
+
+ 42 +
+
+ 1 +
+
+
        Box::new(Constraint::WatchedOr(vec![
+
+
+
+ 43 +
+
+ 1 +
+
+
            Constraint::WInset(Var::NameRef(String::from("a")), vec![Constant::Bool(true)]),
+
+
+
+ 44 +
+
+ 1 +
+
+
            Constraint::WInset(Var::NameRef(String::from("b")), vec![Constant::Bool(false)]),
+
+
+
+ 45 +
+
+ 1 +
+
+
        ])),
+
+
+
+ 46 +
+
+ 1 +
+
+
        Var::NameRef(String::from("c")),
+
+
+
+ 47 +
+
+ 1 +
+
+
    ));
+
+
+
+ 48 +
+
+ 1 +
+
+

+            
+
+
+ 49 +
+
+ 1 +
+
+
    minion_rs::run_minion(model, callback)?;
+
+
+
+ 50 +
+
+ +
+
+

+            
+
+
+ 51 +
+
+ 1 +
+
+
    let guard = SOLS_COUNTER.lock().unwrap();
+
+
+
+ 52 +
+
+ 1 +
+
+
    assert_eq!(*guard, 7);
+
+
+
+ 53 +
+
+ 1 +
+
+
    Ok(())
+
+
+
+ 54 +
+
+ 1 +
+
+
}
+
+
+
+ 55 +
+
+ +
+
+

+            
+
+
+ 56 +
+
+ +
+
+
static SOLS_COUNTER: Mutex<i32> = Mutex::new(0);
+
+
+
+ 57 +
+
+ 7 +
+
+
fn callback(_: HashMap<VarName, Constant>) -> bool {
+
+
+
+ 58 +
+
+ 7 +
+
+
    #[allow(clippy::unwrap_used)]
+
+
+
+ 59 +
+
+ 7 +
+
+
    let mut guard = SOLS_COUNTER.lock().unwrap();
+
+
+
+ 60 +
+
+ 7 +
+
+
    *guard += 1;
+
+
+
+ 61 +
+
+ 7 +
+
+
    true
+
+
+
+ 62 +
+
+ 7 +
+
+
}
+
+
+
+ + +