diff --git a/crates/conjure_core/src/rule_engine/mod.rs b/crates/conjure_core/src/rule_engine/mod.rs index dc6f0e9a68..94e09a9752 100644 --- a/crates/conjure_core/src/rule_engine/mod.rs +++ b/crates/conjure_core/src/rule_engine/mod.rs @@ -51,7 +51,7 @@ pub use conjure_macros::register_rule; /// This macro uses the following syntax: /// /// ```text -/// register_rule_set!(, , (, , ...)); +/// register_rule_set!(, (, , ...)); /// ``` /// /// # Example @@ -59,7 +59,7 @@ pub use conjure_macros::register_rule; /// ```rust /// use conjure_core::rule_engine::register_rule_set; /// -/// register_rule_set!("MyRuleSet", 10, ("DependencyRuleSet", "AnotherRuleSet")); +/// register_rule_set!("MyRuleSet", ("DependencyRuleSet", "AnotherRuleSet")); /// ``` #[doc(inline)] pub use conjure_macros::register_rule_set; @@ -159,8 +159,8 @@ pub fn get_rule_by_name(name: &str) -> Option<&'static Rule<'static>> { /// use conjure_core::rule_engine::register_rule_set; /// use conjure_core::rule_engine::get_rule_sets; /// -/// register_rule_set!("MyRuleSet", 10, ("AnotherRuleSet")); -/// register_rule_set!("AnotherRuleSet", 5, ()); +/// register_rule_set!("MyRuleSet", ("AnotherRuleSet")); +/// register_rule_set!("AnotherRuleSet", ()); /// /// println!("Rule sets: {:?}", get_rule_sets()); /// ``` @@ -168,8 +168,8 @@ pub fn get_rule_by_name(name: &str) -> Option<&'static Rule<'static>> { /// This will print (if no other rule sets are registered): /// ```text /// Rule sets: [ -/// RuleSet { name: "MyRuleSet", order: 10, rules: OnceLock { state: Uninitialized }, dependencies: ["AnotherRuleSet"] }, -/// RuleSet { name: "AnotherRuleSet", order: 5, rules: OnceLock { state: Uninitialized }, dependencies: [] } +/// RuleSet { name: "MyRuleSet", rules: OnceLock { state: Uninitialized }, dependencies: ["AnotherRuleSet"] }, +/// RuleSet { name: "AnotherRuleSet", rules: OnceLock { state: Uninitialized }, dependencies: [] } /// ] /// ``` /// @@ -185,14 +185,14 @@ pub fn get_rule_sets() -> Vec<&'static RuleSet<'static>> { /// use conjure_core::rule_engine::register_rule_set; /// use conjure_core::rule_engine::get_rule_set_by_name; /// -/// register_rule_set!("MyRuleSet", 10, ("DependencyRuleSet", "AnotherRuleSet")); +/// register_rule_set!("MyRuleSet", ("DependencyRuleSet", "AnotherRuleSet")); /// /// println!("Rule set: {:?}", get_rule_set_by_name("MyRuleSet")); /// ``` /// /// This will print: /// ```text -/// Rule set: Some(RuleSet { name: "MyRuleSet", order: 10, rules: OnceLock { state: Uninitialized }, dependencies: ["DependencyRuleSet", "AnotherRuleSet"] }) +/// Rule set: Some(RuleSet { name: "MyRuleSet", rules: OnceLock { state: Uninitialized }, dependencies: ["DependencyRuleSet", "AnotherRuleSet"] }) /// ``` pub fn get_rule_set_by_name(name: &str) -> Option<&'static RuleSet<'static>> { get_rule_sets() diff --git a/crates/conjure_core/src/rule_engine/resolve_rules.rs b/crates/conjure_core/src/rule_engine/resolve_rules.rs index bebd4a0554..fb4052f2ac 100644 --- a/crates/conjure_core/src/rule_engine/resolve_rules.rs +++ b/crates/conjure_core/src/rule_engine/resolve_rules.rs @@ -1,6 +1,7 @@ use std::collections::{HashMap, HashSet}; use std::fmt::Display; +use log::warn; use thiserror::Error; use crate::rule_engine::{get_rule_set_by_name, get_rule_sets_for_solver_family, Rule, RuleSet}; @@ -94,10 +95,8 @@ pub fn get_rule_priorities<'a>( for rs in rule_sets { for (rule, priority) in rs.get_rules() { - if let Some((old_rs, _)) = rule_priorities.get(rule) { - if rs.order >= old_rs.order { - rule_priorities.insert(rule, (rs, *priority)); - } + if rule_priorities.contains_key(rule) { + warn!("Rule {} is defined in multiple rule sets.", rule.name); } else { rule_priorities.insert(rule, (rs, *priority)); } diff --git a/crates/conjure_core/src/rule_engine/rule_set.rs b/crates/conjure_core/src/rule_engine/rule_set.rs index 354b6acf0b..123f3d226f 100644 --- a/crates/conjure_core/src/rule_engine/rule_set.rs +++ b/crates/conjure_core/src/rule_engine/rule_set.rs @@ -31,9 +31,6 @@ use crate::solver::SolverFamily; pub struct RuleSet<'a> { /// The name of the rule set. pub name: &'a str, - /// Order of the RuleSet. Used to establish a consistent order of operations when resolving rules. - /// 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. - pub order: u16, /// A map of rules to their priorities. This will be lazily initialized at runtime. rules: OnceLock, u16>>, /// The names of the rule sets that this rule set depends on. @@ -46,13 +43,11 @@ pub struct RuleSet<'a> { impl<'a> RuleSet<'a> { pub const fn new( name: &'a str, - order: u16, dependencies: &'a [&'a str], solver_families: &'a [SolverFamily], ) -> Self { Self { name, - order, dependency_rs_names: dependencies, solver_families, rules: OnceLock::new(), @@ -181,11 +176,10 @@ impl Display for RuleSet<'_> { f, "RuleSet {{\n\ \tname: {}\n\ - \torder: {}\n\ \trules: {}\n\ \tsolver_families: {:?}\n\ }}", - self.name, self.order, n_rules, solver_families + self.name, n_rules, solver_families ) } } diff --git a/crates/conjure_core/src/rules/base.rs b/crates/conjure_core/src/rules/base.rs index 0ad4587268..555edf9980 100644 --- a/crates/conjure_core/src/rules/base.rs +++ b/crates/conjure_core/src/rules/base.rs @@ -10,7 +10,7 @@ use Atom::*; use Expr::*; use Lit::*; -register_rule_set!("Base", 100, ()); +register_rule_set!("Base", ()); /// This rule simplifies expressions where the operator is applied to an empty set of sub-expressions. /// diff --git a/crates/conjure_core/src/rules/bubble.rs b/crates/conjure_core/src/rules/bubble.rs index ff30361e4a..cbff527d67 100644 --- a/crates/conjure_core/src/rules/bubble.rs +++ b/crates/conjure_core/src/rules/bubble.rs @@ -11,7 +11,7 @@ use crate::ast::{Atom, Literal}; use super::utils::is_all_constant; -register_rule_set!("Bubble", 100, ("Base")); +register_rule_set!("Bubble", ("Base")); // Bubble reduction rules diff --git a/crates/conjure_core/src/rules/cnf.rs b/crates/conjure_core/src/rules/cnf.rs index 4b30ee7c69..4d969e5c6f 100644 --- a/crates/conjure_core/src/rules/cnf.rs +++ b/crates/conjure_core/src/rules/cnf.rs @@ -5,4 +5,4 @@ use conjure_core::rule_engine::register_rule_set; use conjure_core::solver::SolverFamily; -register_rule_set!("CNF", 100, ("Base"), (SolverFamily::SAT)); +register_rule_set!("CNF", ("Base"), (SolverFamily::SAT)); diff --git a/crates/conjure_core/src/rules/constant_eval.rs b/crates/conjure_core/src/rules/constant_eval.rs index 1fcd18f7da..262c9db5f6 100644 --- a/crates/conjure_core/src/rules/constant_eval.rs +++ b/crates/conjure_core/src/rules/constant_eval.rs @@ -8,7 +8,7 @@ use conjure_core::rule_engine::{ use conjure_core::Model; use itertools::izip; -register_rule_set!("Constant", 100, ()); +register_rule_set!("Constant", ()); #[register_rule(("Constant", 9001))] fn apply_eval_constant(expr: &Expr, _: &Model) -> ApplicationResult { diff --git a/crates/conjure_core/src/rules/minion.rs b/crates/conjure_core/src/rules/minion.rs index 81ba92694e..ddb900fa27 100644 --- a/crates/conjure_core/src/rules/minion.rs +++ b/crates/conjure_core/src/rules/minion.rs @@ -19,7 +19,7 @@ use ApplicationError::*; use super::utils::{is_flat, to_aux_var}; -register_rule_set!("Minion", 100, ("Base"), (SolverFamily::Minion)); +register_rule_set!("Minion", ("Base"), (SolverFamily::Minion)); #[register_rule(("Minion", 4200))] fn introduce_producteq(expr: &Expr, model: &Model) -> ApplicationResult { diff --git a/crates/conjure_macros/src/lib.rs b/crates/conjure_macros/src/lib.rs index 4258a6ce84..d3150ac789 100644 --- a/crates/conjure_macros/src/lib.rs +++ b/crates/conjure_macros/src/lib.rs @@ -98,7 +98,6 @@ fn parse_parenthesized(input: ParseStream) -> Result> { struct RuleSetArgs { name: LitStr, - priority: LitInt, dependencies: Vec, solver_families: Vec, } @@ -106,13 +105,10 @@ struct RuleSetArgs { impl Parse for RuleSetArgs { fn parse(input: ParseStream) -> Result { let name = input.parse()?; - input.parse::()?; - let priority = input.parse()?; if input.is_empty() { return Ok(Self { name, - priority, dependencies: Vec::new(), solver_families: Vec::new(), }); @@ -124,7 +120,6 @@ impl Parse for RuleSetArgs { if input.is_empty() { return Ok(Self { name, - priority, dependencies, solver_families: Vec::new(), }); @@ -135,7 +130,6 @@ impl Parse for RuleSetArgs { Ok(Self { name, - priority, dependencies, solver_families, }) @@ -143,19 +137,18 @@ impl Parse for RuleSetArgs { } /** -* Register a rule set with the given name, priority, and dependencies. +* Register a rule set with the given name, dependencies, and metadata. * * # Example * ```rust * use conjure_macros::register_rule_set; - * register_rule_set!("MyRuleSet", 10, ("DependencyRuleSet", "AnotherRuleSet")); + * register_rule_set!("MyRuleSet", ("DependencyRuleSet", "AnotherRuleSet")); * ``` */ #[proc_macro] pub fn register_rule_set(args: TokenStream) -> TokenStream { let RuleSetArgs { name, - priority, dependencies, solver_families, } = parse_macro_input!(args as RuleSetArgs); @@ -174,7 +167,7 @@ pub fn register_rule_set(args: TokenStream) -> TokenStream { let expanded = quote! { use ::conjure_core::rule_engine::_dependencies::*; // ToDo idk if we need to explicitly do that? #[::conjure_core::rule_engine::_dependencies::distributed_slice(::conjure_core::rule_engine::RULE_SETS_DISTRIBUTED_SLICE)] - pub static #static_ident: ::conjure_core::rule_engine::RuleSet<'static> = ::conjure_core::rule_engine::RuleSet::new(#name, #priority, &[#dependencies], &[#solver_families]); + pub static #static_ident: ::conjure_core::rule_engine::RuleSet<'static> = ::conjure_core::rule_engine::RuleSet::new(#name, &[#dependencies], &[#solver_families]); }; TokenStream::from(expanded)