diff --git a/cozo-core/src/cozoscript.pest b/cozo-core/src/cozoscript.pest index 39269165..c34eeb35 100644 --- a/cozo-core/src/cozoscript.pest +++ b/cozo-core/src/cozoscript.pest @@ -7,8 +7,8 @@ */ script = _{sys_script | multi_script | query_script} -query_script = {SOI ~ (option | rule | const_rule | algo_rule)+ ~ EOI} -query_script_inner = {"{" ~ (option | rule | const_rule | algo_rule)+ ~ "}"} +query_script = {SOI ~ (option | rule | const_rule | fixed_rule)+ ~ EOI} +query_script_inner = {"{" ~ (option | rule | const_rule | fixed_rule)+ ~ "}"} multi_script = {SOI ~ query_script_inner+ ~ EOI} sys_script = {SOI ~ "::" ~ (compact_op | list_relations_op | list_relation_op | remove_relations_op | trigger_relation_op | trigger_relation_show_op | rename_relations_op | running_op | kill_op | explain_op | access_level_op) ~ EOI} @@ -48,19 +48,19 @@ compound_ident = @{ident ~ ("." ~ ident)?} rule = {rule_head ~ ":=" ~ rule_body ~ ";"?} const_rule = {rule_head ~ "<-" ~ expr ~ ";"?} -algo_rule = {rule_head ~ "<~" ~ ident ~ algo_args_list ~ ";"?} -algo_args_list = {"(" ~ (algo_arg ~ ",")* ~ algo_arg? ~ ")"} +fixed_rule = {rule_head ~ "<~" ~ ident ~ fixed_args_list ~ ";"?} +fixed_args_list = {"(" ~ (fixed_arg ~ ",")* ~ fixed_arg? ~ ")"} rule_head = {(prog_entry | ident) ~ "[" ~ (head_arg ~ ",")* ~ head_arg? ~ "]"} head_arg = {aggr_arg | var} aggr_arg = {ident ~ "(" ~ var ~ ("," ~ expr)* ~ ")"} -algo_arg = _{algo_rel | algo_opt_pair} -algo_opt_pair = {ident ~ ":" ~ expr} -algo_rel = {algo_rule_rel | algo_relation_rel | algo_named_relation_rel } -algo_rule_rel = {ident ~ "[" ~ (var ~ ",")* ~ var? ~ "]"} -algo_relation_rel = {relation_ident ~ "[" ~ (var ~ ",")* ~ var? ~ "]"} -algo_named_relation_rel = {relation_ident ~ "{" ~ (algo_named_relation_arg_pair ~ ",")* ~ algo_named_relation_arg_pair? ~ "}"} -algo_named_relation_arg_pair = {ident ~ (":" ~ ident)?} +fixed_arg = _{fixed_rel | fixed_opt_pair} +fixed_opt_pair = {ident ~ ":" ~ expr} +fixed_rel = {fixed_rule_rel | fixed_relation_rel | fixed_named_relation_rel } +fixed_rule_rel = {ident ~ "[" ~ (var ~ ",")* ~ var? ~ "]"} +fixed_relation_rel = {relation_ident ~ "[" ~ (var ~ ",")* ~ var? ~ "]"} +fixed_named_relation_rel = {relation_ident ~ "{" ~ (fixed_named_relation_arg_pair ~ ",")* ~ fixed_named_relation_arg_pair? ~ "}"} +fixed_named_relation_arg_pair = {ident ~ (":" ~ ident)?} rule_body = {(disjunction ~ ",")* ~ disjunction?} rule_apply = {underscore_ident ~ "[" ~ apply_args ~ "]"} diff --git a/cozo-core/src/data/program.rs b/cozo-core/src/data/program.rs index c32dc77e..94615a4c 100644 --- a/cozo-core/src/data/program.rs +++ b/cozo-core/src/data/program.rs @@ -17,12 +17,12 @@ use smallvec::SmallVec; use smartstring::{LazyCompact, SmartString}; use thiserror::Error; -use crate::algo::{AlgoHandle, AlgoImpl}; use crate::data::aggr::Aggregation; use crate::data::expr::Expr; use crate::data::relation::StoredRelationMetadata; use crate::data::symb::{Symbol, PROG_ENTRY}; use crate::data::value::DataValue; +use crate::fixed_rule::{FixedRule, FixedRuleHandle}; use crate::parse::SourceSpan; use crate::runtime::relation::InputRelationHandle; use crate::runtime::temp_store::EpochStore; @@ -187,78 +187,80 @@ impl TempSymbGen { } #[derive(Debug)] -pub(crate) enum InputInlineRulesOrAlgo { +pub(crate) enum InputInlineRulesOrFixed { Rules { rules: Vec }, - Algo { algo: AlgoApply }, + Fixed { fixed: FixedRuleApply }, } -impl InputInlineRulesOrAlgo { +impl InputInlineRulesOrFixed { pub(crate) fn first_span(&self) -> SourceSpan { match self { - InputInlineRulesOrAlgo::Rules { rules, .. } => rules[0].span, - InputInlineRulesOrAlgo::Algo { algo, .. } => algo.span, + InputInlineRulesOrFixed::Rules { rules, .. } => rules[0].span, + InputInlineRulesOrFixed::Fixed { fixed, .. } => fixed.span, } } } -pub(crate) struct AlgoApply { - pub(crate) algo: AlgoHandle, - pub(crate) rule_args: Vec, +pub(crate) struct FixedRuleApply { + pub(crate) fixed_handle: FixedRuleHandle, + pub(crate) rule_args: Vec, pub(crate) options: Rc, Expr>>, pub(crate) head: Vec, pub(crate) arity: usize, pub(crate) span: SourceSpan, - pub(crate) algo_impl: Arc>, + pub(crate) fixed_impl: Arc>, } -impl AlgoApply { +impl FixedRuleApply { pub(crate) fn arity(&self) -> Result { - self.algo_impl.as_ref().arity(&self.options, &self.head, self.span) + self.fixed_impl + .as_ref() + .arity(&self.options, &self.head, self.span) } } -impl Debug for AlgoApply { +impl Debug for FixedRuleApply { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.debug_struct("AlgoApply") - .field("algo", &self.algo.name) + f.debug_struct("FixedRuleApply") + .field("name", &self.fixed_handle.name) .field("rules", &self.rule_args) .field("options", &self.options) .finish() } } -pub(crate) struct MagicAlgoApply { - pub(crate) algo: AlgoHandle, - pub(crate) rule_args: Vec, +pub(crate) struct MagicFixedRuleApply { + pub(crate) fixed_handle: FixedRuleHandle, + pub(crate) rule_args: Vec, pub(crate) options: Rc, Expr>>, pub(crate) span: SourceSpan, pub(crate) arity: usize, - pub(crate) algo_impl: Arc>, + pub(crate) fixed_impl: Arc>, } #[derive(Error, Diagnostic, Debug)] -#[error("Cannot find a required named option '{name}' for '{algo_name}'")] -#[diagnostic(code(algo::arg_not_found))] -pub(crate) struct AlgoOptionNotFoundError { +#[error("Cannot find a required named option '{name}' for '{rule_name}'")] +#[diagnostic(code(fixed_rule::arg_not_found))] +pub(crate) struct FixedRuleOptionNotFoundError { pub(crate) name: String, #[label] pub(crate) span: SourceSpan, - pub(crate) algo_name: String, + pub(crate) rule_name: String, } #[derive(Error, Diagnostic, Debug)] -#[error("Wrong value for option '{name}' of '{algo_name}'")] -#[diagnostic(code(algo::arg_wrong))] -pub(crate) struct WrongAlgoOptionError { +#[error("Wrong value for option '{name}' of '{rule_name}'")] +#[diagnostic(code(fixed_rule::arg_wrong))] +pub(crate) struct WrongFixedRuleOptionError { pub(crate) name: String, #[label] pub(crate) span: SourceSpan, - pub(crate) algo_name: String, + pub(crate) rule_name: String, #[help] pub(crate) help: String, } -impl MagicAlgoApply { +impl MagicFixedRuleApply { #[allow(dead_code)] pub(crate) fn relation_with_min_len( &self, @@ -266,11 +268,11 @@ impl MagicAlgoApply { len: usize, tx: &SessionTx<'_>, stores: &BTreeMap, - ) -> Result<&MagicAlgoRuleArg> { + ) -> Result<&MagicFixedRuleRuleArg> { #[derive(Error, Diagnostic, Debug)] - #[error("Input relation to algorithm has insufficient arity")] + #[error("Input relation to fixed rule has insufficient arity")] #[diagnostic(help("Arity should be at least {0} but is {1}"))] - #[diagnostic(code(algo::input_relation_bad_arity))] + #[diagnostic(code(fixed_rule::input_relation_bad_arity))] struct InputRelationArityError(usize, usize, #[label] SourceSpan); let rel = self.relation(idx)?; @@ -281,39 +283,39 @@ impl MagicAlgoApply { ); Ok(rel) } - pub(crate) fn relation(&self, idx: usize) -> Result<&MagicAlgoRuleArg> { + pub(crate) fn relation(&self, idx: usize) -> Result<&MagicFixedRuleRuleArg> { #[derive(Error, Diagnostic, Debug)] - #[error("Cannot find a required positional argument at index {idx} for '{algo_name}'")] - #[diagnostic(code(algo::not_enough_args))] - pub(crate) struct AlgoNotEnoughRelationError { + #[error("Cannot find a required positional argument at index {idx} for '{rule_name}'")] + #[diagnostic(code(fixed_rule::not_enough_args))] + pub(crate) struct FixedRuleNotEnoughRelationError { idx: usize, #[label] span: SourceSpan, - algo_name: String, + rule_name: String, } Ok(self .rule_args .get(idx) - .ok_or_else(|| AlgoNotEnoughRelationError { + .ok_or_else(|| FixedRuleNotEnoughRelationError { idx, span: self.span, - algo_name: self.algo.name.to_string(), + rule_name: self.fixed_handle.name.to_string(), })?) } } -impl Debug for MagicAlgoApply { +impl Debug for MagicFixedRuleApply { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.debug_struct("AlgoApply") - .field("algo", &self.algo.name) + f.debug_struct("FixedRuleApply") + .field("name", &self.fixed_handle.name) .field("rules", &self.rule_args) .field("options", &self.options) .finish() } } -pub(crate) enum AlgoRuleArg { +pub(crate) enum FixedRuleArg { InMem { name: Symbol, bindings: Vec, @@ -331,24 +333,24 @@ pub(crate) enum AlgoRuleArg { }, } -impl Debug for AlgoRuleArg { +impl Debug for FixedRuleArg { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self) } } -impl Display for AlgoRuleArg { +impl Display for FixedRuleArg { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { - AlgoRuleArg::InMem { name, bindings, .. } => { + FixedRuleArg::InMem { name, bindings, .. } => { write!(f, "{}", name)?; f.debug_list().entries(bindings).finish()?; } - AlgoRuleArg::Stored { name, bindings, .. } => { + FixedRuleArg::Stored { name, bindings, .. } => { write!(f, ":{}", name)?; f.debug_list().entries(bindings).finish()?; } - AlgoRuleArg::NamedStored { name, bindings, .. } => { + FixedRuleArg::NamedStored { name, bindings, .. } => { write!(f, "*")?; let mut sf = f.debug_struct(name); for (k, v) in bindings { @@ -362,7 +364,7 @@ impl Display for AlgoRuleArg { } #[derive(Debug)] -pub(crate) enum MagicAlgoRuleArg { +pub(crate) enum MagicFixedRuleRuleArg { InMem { name: MagicSymbol, bindings: Vec, @@ -375,24 +377,25 @@ pub(crate) enum MagicAlgoRuleArg { }, } -impl MagicAlgoRuleArg { +impl MagicFixedRuleRuleArg { #[allow(dead_code)] pub(crate) fn bindings(&self) -> &[Symbol] { match self { - MagicAlgoRuleArg::InMem { bindings, .. } - | MagicAlgoRuleArg::Stored { bindings, .. } => bindings, + MagicFixedRuleRuleArg::InMem { bindings, .. } + | MagicFixedRuleRuleArg::Stored { bindings, .. } => bindings, } } #[allow(dead_code)] pub(crate) fn span(&self) -> SourceSpan { match self { - MagicAlgoRuleArg::InMem { span, .. } | MagicAlgoRuleArg::Stored { span, .. } => *span, + MagicFixedRuleRuleArg::InMem { span, .. } + | MagicFixedRuleRuleArg::Stored { span, .. } => *span, } } pub(crate) fn get_binding_map(&self, starting: usize) -> BTreeMap { let bindings = match self { - MagicAlgoRuleArg::InMem { bindings, .. } - | MagicAlgoRuleArg::Stored { bindings, .. } => bindings, + MagicFixedRuleRuleArg::InMem { bindings, .. } + | MagicFixedRuleRuleArg::Stored { bindings, .. } => bindings, }; bindings .iter() @@ -404,7 +407,7 @@ impl MagicAlgoRuleArg { #[derive(Debug)] pub(crate) struct InputProgram { - pub(crate) prog: BTreeMap, + pub(crate) prog: BTreeMap, pub(crate) out_opts: QueryOutOptions, } @@ -412,7 +415,7 @@ impl Display for InputProgram { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { for (name, rules) in &self.prog { match rules { - InputInlineRulesOrAlgo::Rules { rules, .. } => { + InputInlineRulesOrFixed::Rules { rules, .. } => { for InputInlineRule { head, aggr, body, .. } in rules @@ -443,10 +446,10 @@ impl Display for InputProgram { writeln!(f, ";")?; } } - InputInlineRulesOrAlgo::Algo { - algo: - AlgoApply { - algo, + InputInlineRulesOrFixed::Fixed { + fixed: + FixedRuleApply { + fixed_handle: handle, rule_args, options, head, @@ -456,7 +459,7 @@ impl Display for InputProgram { write!(f, "{}", name)?; f.debug_list().entries(head).finish()?; write!(f, " <~ ")?; - write!(f, "{}(", algo.name)?; + write!(f, "{}(", handle.name)?; let mut first = true; for rule_arg in rule_args { if first { @@ -499,8 +502,8 @@ impl InputProgram { pub(crate) fn get_entry_arity(&self) -> Result { if let Some(entry) = self.prog.get(&Symbol::new(PROG_ENTRY, SourceSpan(0, 0))) { return match entry { - InputInlineRulesOrAlgo::Rules { rules } => Ok(rules.last().unwrap().head.len()), - InputInlineRulesOrAlgo::Algo { algo: algo_apply } => algo_apply.arity(), + InputInlineRulesOrFixed::Rules { rules } => Ok(rules.last().unwrap().head.len()), + InputInlineRulesOrFixed::Fixed { fixed } => fixed.arity(), }; } @@ -520,7 +523,7 @@ impl InputProgram { pub(crate) fn get_entry_out_head(&self) -> Result> { if let Some(entry) = self.prog.get(&Symbol::new(PROG_ENTRY, SourceSpan(0, 0))) { return match entry { - InputInlineRulesOrAlgo::Rules { rules } => { + InputInlineRulesOrFixed::Rules { rules } => { let head = &rules.last().unwrap().head; let mut ret = Vec::with_capacity(head.len()); let aggrs = &rules.last().unwrap().aggr; @@ -543,11 +546,11 @@ impl InputProgram { } Ok(ret) } - InputInlineRulesOrAlgo::Algo { algo: algo_apply } => { - if algo_apply.head.is_empty() { + InputInlineRulesOrFixed::Fixed { fixed } => { + if fixed.head.is_empty() { Err(EntryHeadNotExplicitlyDefinedError(entry.first_span()).into()) } else { - Ok(algo_apply.head.to_vec()) + Ok(fixed.head.to_vec()) } } }; @@ -560,9 +563,9 @@ impl InputProgram { tx: &SessionTx<'_>, ) -> Result<(NormalFormProgram, QueryOutOptions)> { let mut prog: BTreeMap = Default::default(); - for (k, rules_or_algo) in self.prog { - match rules_or_algo { - InputInlineRulesOrAlgo::Rules { rules } => { + for (k, rules_or_fixed) in self.prog { + match rules_or_fixed { + InputInlineRulesOrFixed::Rules { rules } => { let mut collected_rules = vec![]; for rule in rules { let mut counter = -1; @@ -615,13 +618,13 @@ impl InputProgram { } prog.insert( k.clone(), - NormalFormAlgoOrRules::Rules { + NormalFormRulesOrFixed::Rules { rules: collected_rules, }, ); } - InputInlineRulesOrAlgo::Algo { algo: algo_apply } => { - prog.insert(k.clone(), NormalFormAlgoOrRules::Algo { algo: algo_apply }); + InputInlineRulesOrFixed::Fixed { fixed } => { + prog.insert(k.clone(), NormalFormRulesOrFixed::Fixed { fixed }); } } } @@ -633,58 +636,58 @@ impl InputProgram { pub(crate) struct StratifiedNormalFormProgram(pub(crate) Vec); #[derive(Debug)] -pub(crate) enum NormalFormAlgoOrRules { +pub(crate) enum NormalFormRulesOrFixed { Rules { rules: Vec }, - Algo { algo: AlgoApply }, + Fixed { fixed: FixedRuleApply }, } -impl NormalFormAlgoOrRules { +impl NormalFormRulesOrFixed { pub(crate) fn rules(&self) -> Option<&[NormalFormInlineRule]> { match self { - NormalFormAlgoOrRules::Rules { rules: r } => Some(r), - NormalFormAlgoOrRules::Algo { algo: _ } => None, + NormalFormRulesOrFixed::Rules { rules: r } => Some(r), + NormalFormRulesOrFixed::Fixed { fixed: _ } => None, } } } #[derive(Debug, Default)] pub(crate) struct NormalFormProgram { - pub(crate) prog: BTreeMap, + pub(crate) prog: BTreeMap, } #[derive(Debug)] pub(crate) struct StratifiedMagicProgram(pub(crate) Vec); #[derive(Debug)] -pub(crate) enum MagicRulesOrAlgo { +pub(crate) enum MagicRulesOrFixed { Rules { rules: Vec }, - Algo { algo: MagicAlgoApply }, + Fixed { fixed: MagicFixedRuleApply }, } -impl Default for MagicRulesOrAlgo { +impl Default for MagicRulesOrFixed { fn default() -> Self { Self::Rules { rules: vec![] } } } -impl MagicRulesOrAlgo { +impl MagicRulesOrFixed { pub(crate) fn arity(&self) -> Result { Ok(match self { - MagicRulesOrAlgo::Rules { rules } => rules.first().unwrap().head.len(), - MagicRulesOrAlgo::Algo { algo } => algo.arity, + MagicRulesOrFixed::Rules { rules } => rules.first().unwrap().head.len(), + MagicRulesOrFixed::Fixed { fixed } => fixed.arity, }) } pub(crate) fn mut_rules(&mut self) -> Option<&mut Vec> { match self { - MagicRulesOrAlgo::Rules { rules } => Some(rules), - MagicRulesOrAlgo::Algo { algo: _ } => None, + MagicRulesOrFixed::Rules { rules } => Some(rules), + MagicRulesOrFixed::Fixed { fixed: _ } => None, } } } #[derive(Debug)] pub(crate) struct MagicProgram { - pub(crate) prog: BTreeMap, + pub(crate) prog: BTreeMap, } #[derive(Clone, Ord, PartialOrd, Eq, PartialEq)] diff --git a/cozo-core/src/algo/all_pairs_shortest_path.rs b/cozo-core/src/fixed_rule/algos/all_pairs_shortest_path.rs similarity index 94% rename from cozo-core/src/algo/all_pairs_shortest_path.rs rename to cozo-core/src/fixed_rule/algos/all_pairs_shortest_path.rs index 4b2c8cfb..fa1420a1 100644 --- a/cozo-core/src/algo/all_pairs_shortest_path.rs +++ b/cozo-core/src/fixed_rule/algos/all_pairs_shortest_path.rs @@ -17,8 +17,8 @@ use priority_queue::PriorityQueue; use rayon::prelude::*; use smartstring::{LazyCompact, SmartString}; -use crate::algo::shortest_path_dijkstra::dijkstra_keep_ties; -use crate::algo::{AlgoImpl, AlgoPayload}; +use crate::fixed_rule::algos::shortest_path_dijkstra::dijkstra_keep_ties; +use crate::fixed_rule::{FixedRule, FixedRulePayload}; use crate::data::expr::Expr; use crate::data::symb::Symbol; use crate::data::value::DataValue; @@ -28,10 +28,10 @@ use crate::runtime::temp_store::RegularTempStore; pub(crate) struct BetweennessCentrality; -impl AlgoImpl for BetweennessCentrality { +impl FixedRule for BetweennessCentrality { fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, poison: Poison, ) -> Result<()> { @@ -100,10 +100,10 @@ impl AlgoImpl for BetweennessCentrality { pub(crate) struct ClosenessCentrality; -impl AlgoImpl for ClosenessCentrality { +impl FixedRule for ClosenessCentrality { fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, poison: Poison, ) -> Result<()> { diff --git a/cozo-core/src/algo/astar.rs b/cozo-core/src/fixed_rule/algos/astar.rs similarity index 95% rename from cozo-core/src/algo/astar.rs rename to cozo-core/src/fixed_rule/algos/astar.rs index 2dcc3730..582d512f 100644 --- a/cozo-core/src/algo/astar.rs +++ b/cozo-core/src/fixed_rule/algos/astar.rs @@ -14,7 +14,7 @@ use ordered_float::OrderedFloat; use priority_queue::PriorityQueue; use smartstring::{LazyCompact, SmartString}; -use crate::algo::{AlgoImpl, AlgoInputRelation, AlgoPayload, BadExprValueError, NodeNotFoundError}; +use crate::fixed_rule::{FixedRule, FixedRuleInputRelation, FixedRulePayload, BadExprValueError, NodeNotFoundError}; use crate::data::expr::Expr; use crate::data::symb::Symbol; use crate::data::tuple::Tuple; @@ -25,10 +25,10 @@ use crate::runtime::temp_store::RegularTempStore; pub(crate) struct ShortestPathAStar; -impl AlgoImpl for ShortestPathAStar { +impl FixedRule for ShortestPathAStar { fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, poison: Poison, ) -> Result<()> { @@ -72,8 +72,8 @@ impl AlgoImpl for ShortestPathAStar { fn astar( starting: &Tuple, goal: &Tuple, - edges: AlgoInputRelation<'_, '_>, - nodes: AlgoInputRelation<'_, '_>, + edges: FixedRuleInputRelation<'_, '_>, + nodes: FixedRuleInputRelation<'_, '_>, heuristic: &Expr, poison: Poison, ) -> Result<(f64, Vec)> { diff --git a/cozo-core/src/algo/bfs.rs b/cozo-core/src/fixed_rule/algos/bfs.rs similarity index 96% rename from cozo-core/src/algo/bfs.rs rename to cozo-core/src/fixed_rule/algos/bfs.rs index c3e3e1f4..82c00a1b 100644 --- a/cozo-core/src/algo/bfs.rs +++ b/cozo-core/src/fixed_rule/algos/bfs.rs @@ -11,7 +11,7 @@ use std::collections::{BTreeMap, BTreeSet, VecDeque}; use miette::Result; use smartstring::{LazyCompact, SmartString}; -use crate::algo::{AlgoImpl, AlgoPayload, NodeNotFoundError}; +use crate::fixed_rule::{FixedRule, FixedRulePayload, NodeNotFoundError}; use crate::data::expr::Expr; use crate::data::symb::Symbol; use crate::data::value::DataValue; @@ -21,10 +21,10 @@ use crate::runtime::temp_store::RegularTempStore; pub(crate) struct Bfs; -impl AlgoImpl for Bfs { +impl FixedRule for Bfs { fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, poison: Poison, ) -> Result<()> { diff --git a/cozo-core/src/algo/degree_centrality.rs b/cozo-core/src/fixed_rule/algos/degree_centrality.rs similarity index 94% rename from cozo-core/src/algo/degree_centrality.rs rename to cozo-core/src/fixed_rule/algos/degree_centrality.rs index e7dddfe1..02857e9d 100644 --- a/cozo-core/src/algo/degree_centrality.rs +++ b/cozo-core/src/fixed_rule/algos/degree_centrality.rs @@ -11,7 +11,7 @@ use std::collections::BTreeMap; use miette::Result; use smartstring::{LazyCompact, SmartString}; -use crate::algo::{AlgoImpl, AlgoPayload}; +use crate::fixed_rule::{FixedRule, FixedRulePayload}; use crate::data::expr::Expr; use crate::data::symb::Symbol; use crate::data::value::DataValue; @@ -21,10 +21,10 @@ use crate::runtime::temp_store::RegularTempStore; pub(crate) struct DegreeCentrality; -impl AlgoImpl for DegreeCentrality { +impl FixedRule for DegreeCentrality { fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, poison: Poison, ) -> Result<()> { diff --git a/cozo-core/src/algo/dfs.rs b/cozo-core/src/fixed_rule/algos/dfs.rs similarity index 96% rename from cozo-core/src/algo/dfs.rs rename to cozo-core/src/fixed_rule/algos/dfs.rs index ff161f1e..765e6087 100644 --- a/cozo-core/src/algo/dfs.rs +++ b/cozo-core/src/fixed_rule/algos/dfs.rs @@ -11,7 +11,7 @@ use std::collections::{BTreeMap, BTreeSet}; use miette::Result; use smartstring::{LazyCompact, SmartString}; -use crate::algo::{AlgoImpl, AlgoPayload, NodeNotFoundError}; +use crate::fixed_rule::{FixedRule, FixedRulePayload, NodeNotFoundError}; use crate::data::expr::Expr; use crate::data::symb::Symbol; use crate::data::value::DataValue; @@ -21,10 +21,10 @@ use crate::runtime::temp_store::RegularTempStore; pub(crate) struct Dfs; -impl AlgoImpl for Dfs { +impl FixedRule for Dfs { fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, poison: Poison, ) -> Result<()> { diff --git a/cozo-core/src/algo/kruskal.rs b/cozo-core/src/fixed_rule/algos/kruskal.rs similarity index 95% rename from cozo-core/src/algo/kruskal.rs rename to cozo-core/src/fixed_rule/algos/kruskal.rs index 7de8c9cb..7e30d2be 100644 --- a/cozo-core/src/algo/kruskal.rs +++ b/cozo-core/src/fixed_rule/algos/kruskal.rs @@ -15,7 +15,7 @@ use ordered_float::OrderedFloat; use priority_queue::PriorityQueue; use smartstring::{LazyCompact, SmartString}; -use crate::algo::{AlgoImpl, AlgoPayload}; +use crate::fixed_rule::{FixedRule, FixedRulePayload}; use crate::data::expr::Expr; use crate::data::symb::Symbol; use crate::data::value::DataValue; @@ -25,10 +25,10 @@ use crate::runtime::temp_store::RegularTempStore; pub(crate) struct MinimumSpanningForestKruskal; -impl AlgoImpl for MinimumSpanningForestKruskal { +impl FixedRule for MinimumSpanningForestKruskal { fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, poison: Poison, ) -> Result<()> { diff --git a/cozo-core/src/algo/label_propagation.rs b/cozo-core/src/fixed_rule/algos/label_propagation.rs similarity index 95% rename from cozo-core/src/algo/label_propagation.rs rename to cozo-core/src/fixed_rule/algos/label_propagation.rs index b385b6de..4162cc4b 100644 --- a/cozo-core/src/algo/label_propagation.rs +++ b/cozo-core/src/fixed_rule/algos/label_propagation.rs @@ -13,7 +13,7 @@ use miette::Result; use rand::prelude::*; use smartstring::{LazyCompact, SmartString}; -use crate::algo::{AlgoImpl, AlgoPayload}; +use crate::fixed_rule::{FixedRule, FixedRulePayload}; use crate::data::expr::Expr; use crate::data::symb::Symbol; use crate::data::value::DataValue; @@ -23,10 +23,10 @@ use crate::runtime::temp_store::RegularTempStore; pub(crate) struct LabelPropagation; -impl AlgoImpl for LabelPropagation { +impl FixedRule for LabelPropagation { fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, poison: Poison, ) -> Result<()> { diff --git a/cozo-core/src/algo/louvain.rs b/cozo-core/src/fixed_rule/algos/louvain.rs similarity index 97% rename from cozo-core/src/algo/louvain.rs rename to cozo-core/src/fixed_rule/algos/louvain.rs index 53b25592..a6a26ff6 100644 --- a/cozo-core/src/algo/louvain.rs +++ b/cozo-core/src/fixed_rule/algos/louvain.rs @@ -13,7 +13,7 @@ use log::debug; use miette::Result; use smartstring::{LazyCompact, SmartString}; -use crate::algo::{AlgoImpl, AlgoPayload}; +use crate::fixed_rule::{FixedRule, FixedRulePayload}; use crate::data::expr::Expr; use crate::data::symb::Symbol; use crate::data::value::DataValue; @@ -23,10 +23,10 @@ use crate::runtime::temp_store::RegularTempStore; pub(crate) struct CommunityDetectionLouvain; -impl AlgoImpl for CommunityDetectionLouvain { +impl FixedRule for CommunityDetectionLouvain { fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, poison: Poison, ) -> Result<()> { @@ -255,7 +255,7 @@ fn louvain_step( mod tests { use itertools::Itertools; - use crate::algo::louvain::louvain; + use crate::fixed_rule::algos::louvain::louvain; use crate::runtime::db::Poison; #[test] diff --git a/cozo-core/src/fixed_rule/algos/mod.rs b/cozo-core/src/fixed_rule/algos/mod.rs new file mode 100644 index 00000000..c93e1b22 --- /dev/null +++ b/cozo-core/src/fixed_rule/algos/mod.rs @@ -0,0 +1,37 @@ +/* + * Copyright 2022, The Cozo Project Authors. + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#[cfg(feature = "graph-algo")] +pub(crate) mod all_pairs_shortest_path; +#[cfg(feature = "graph-algo")] +pub(crate) mod astar; +#[cfg(feature = "graph-algo")] +pub(crate) mod bfs; +#[cfg(feature = "graph-algo")] +pub(crate) mod degree_centrality; +#[cfg(feature = "graph-algo")] +pub(crate) mod dfs; +#[cfg(feature = "graph-algo")] +pub(crate) mod kruskal; +#[cfg(feature = "graph-algo")] +pub(crate) mod label_propagation; +#[cfg(feature = "graph-algo")] +pub(crate) mod louvain; +#[cfg(feature = "graph-algo")] +pub(crate) mod pagerank; +#[cfg(feature = "graph-algo")] +pub(crate) mod prim; +#[cfg(feature = "graph-algo")] +pub(crate) mod shortest_path_dijkstra; +pub(crate) mod strongly_connected_components; +#[cfg(feature = "graph-algo")] +pub(crate) mod top_sort; +#[cfg(feature = "graph-algo")] +pub(crate) mod triangles; +#[cfg(feature = "graph-algo")] +pub(crate) mod yen; diff --git a/cozo-core/src/algo/pagerank.rs b/cozo-core/src/fixed_rule/algos/pagerank.rs similarity index 96% rename from cozo-core/src/algo/pagerank.rs rename to cozo-core/src/fixed_rule/algos/pagerank.rs index 33c8cd23..34d94a92 100644 --- a/cozo-core/src/algo/pagerank.rs +++ b/cozo-core/src/fixed_rule/algos/pagerank.rs @@ -17,7 +17,7 @@ use miette::Result; use nalgebra::{Dynamic, OMatrix, U1}; use smartstring::{LazyCompact, SmartString}; -use crate::algo::{AlgoImpl, AlgoPayload}; +use crate::fixed_rule::{FixedRule, FixedRulePayload}; use crate::data::expr::Expr; use crate::data::symb::Symbol; use crate::data::value::DataValue; @@ -27,11 +27,11 @@ use crate::runtime::temp_store::RegularTempStore; pub(crate) struct PageRank; -impl AlgoImpl for PageRank { +impl FixedRule for PageRank { #[allow(unused_variables)] fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, poison: Poison, ) -> Result<()> { diff --git a/cozo-core/src/algo/prim.rs b/cozo-core/src/fixed_rule/algos/prim.rs similarity index 96% rename from cozo-core/src/algo/prim.rs rename to cozo-core/src/fixed_rule/algos/prim.rs index 81e3ea4a..28ec85fa 100644 --- a/cozo-core/src/algo/prim.rs +++ b/cozo-core/src/fixed_rule/algos/prim.rs @@ -16,7 +16,7 @@ use priority_queue::PriorityQueue; use smartstring::{LazyCompact, SmartString}; use thiserror::Error; -use crate::algo::{AlgoImpl, AlgoPayload}; +use crate::fixed_rule::{FixedRule, FixedRulePayload}; use crate::data::expr::Expr; use crate::data::symb::Symbol; use crate::data::value::DataValue; @@ -26,10 +26,10 @@ use crate::runtime::temp_store::RegularTempStore; pub(crate) struct MinimumSpanningTreePrim; -impl AlgoImpl for MinimumSpanningTreePrim { +impl FixedRule for MinimumSpanningTreePrim { fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, poison: Poison, ) -> Result<()> { diff --git a/cozo-core/src/algo/shortest_path_dijkstra.rs b/cozo-core/src/fixed_rule/algos/shortest_path_dijkstra.rs similarity index 98% rename from cozo-core/src/algo/shortest_path_dijkstra.rs rename to cozo-core/src/fixed_rule/algos/shortest_path_dijkstra.rs index b04ebc30..c17eb91d 100644 --- a/cozo-core/src/algo/shortest_path_dijkstra.rs +++ b/cozo-core/src/fixed_rule/algos/shortest_path_dijkstra.rs @@ -19,7 +19,7 @@ use rayon::prelude::*; use smallvec::{smallvec, SmallVec}; use smartstring::{LazyCompact, SmartString}; -use crate::algo::{AlgoImpl, AlgoPayload}; +use crate::fixed_rule::{FixedRule, FixedRulePayload}; use crate::data::expr::Expr; use crate::data::symb::Symbol; use crate::data::value::DataValue; @@ -29,10 +29,10 @@ use crate::runtime::temp_store::RegularTempStore; pub(crate) struct ShortestPathDijkstra; -impl AlgoImpl for ShortestPathDijkstra { +impl FixedRule for ShortestPathDijkstra { fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, poison: Poison, ) -> Result<()> { diff --git a/cozo-core/src/algo/strongly_connected_components.rs b/cozo-core/src/fixed_rule/algos/strongly_connected_components.rs similarity index 95% rename from cozo-core/src/algo/strongly_connected_components.rs rename to cozo-core/src/fixed_rule/algos/strongly_connected_components.rs index 98b85e0a..f8126c13 100644 --- a/cozo-core/src/algo/strongly_connected_components.rs +++ b/cozo-core/src/fixed_rule/algos/strongly_connected_components.rs @@ -14,9 +14,9 @@ use itertools::Itertools; use miette::Result; use smartstring::{LazyCompact, SmartString}; -use crate::algo::{AlgoImpl, AlgoPayload}; +use crate::fixed_rule::{FixedRule, FixedRulePayload}; use crate::data::expr::Expr; -use crate::data::program::{MagicAlgoApply, MagicSymbol}; +use crate::data::program::{MagicFixedRuleApply, MagicSymbol}; use crate::data::symb::Symbol; use crate::data::tuple::Tuple; use crate::data::value::DataValue; @@ -37,10 +37,10 @@ impl StronglyConnectedComponent { } #[cfg(feature = "graph-algo")] -impl AlgoImpl for StronglyConnectedComponent { +impl FixedRule for StronglyConnectedComponent { fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, poison: Poison, ) -> Result<()> { diff --git a/cozo-core/src/algo/top_sort.rs b/cozo-core/src/fixed_rule/algos/top_sort.rs similarity index 94% rename from cozo-core/src/algo/top_sort.rs rename to cozo-core/src/fixed_rule/algos/top_sort.rs index 9a4ae2c1..980af9de 100644 --- a/cozo-core/src/algo/top_sort.rs +++ b/cozo-core/src/fixed_rule/algos/top_sort.rs @@ -11,7 +11,7 @@ use std::collections::BTreeMap; use miette::Result; use smartstring::{LazyCompact, SmartString}; -use crate::algo::{AlgoImpl, AlgoPayload}; +use crate::fixed_rule::{FixedRule, FixedRulePayload}; use crate::data::expr::Expr; use crate::data::symb::Symbol; use crate::data::value::DataValue; @@ -21,10 +21,10 @@ use crate::runtime::temp_store::RegularTempStore; pub(crate) struct TopSort; -impl AlgoImpl for TopSort { +impl FixedRule for TopSort { fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, poison: Poison, ) -> Result<()> { diff --git a/cozo-core/src/algo/triangles.rs b/cozo-core/src/fixed_rule/algos/triangles.rs similarity index 94% rename from cozo-core/src/algo/triangles.rs rename to cozo-core/src/fixed_rule/algos/triangles.rs index 59584f93..74191bf7 100644 --- a/cozo-core/src/algo/triangles.rs +++ b/cozo-core/src/fixed_rule/algos/triangles.rs @@ -13,7 +13,7 @@ use miette::Result; use rayon::prelude::*; use smartstring::{LazyCompact, SmartString}; -use crate::algo::{AlgoImpl, AlgoPayload}; +use crate::fixed_rule::{FixedRule, FixedRulePayload}; use crate::data::expr::Expr; use crate::data::symb::Symbol; use crate::data::value::DataValue; @@ -23,10 +23,10 @@ use crate::runtime::temp_store::RegularTempStore; pub(crate) struct ClusteringCoefficients; -impl AlgoImpl for ClusteringCoefficients { +impl FixedRule for ClusteringCoefficients { fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, poison: Poison, ) -> Result<()> { diff --git a/cozo-core/src/algo/yen.rs b/cozo-core/src/fixed_rule/algos/yen.rs similarity index 97% rename from cozo-core/src/algo/yen.rs rename to cozo-core/src/fixed_rule/algos/yen.rs index c6284b18..6fc8ace6 100644 --- a/cozo-core/src/algo/yen.rs +++ b/cozo-core/src/fixed_rule/algos/yen.rs @@ -14,8 +14,8 @@ use miette::Result; use rayon::prelude::*; use smartstring::{LazyCompact, SmartString}; -use crate::algo::shortest_path_dijkstra::dijkstra; -use crate::algo::{AlgoImpl, AlgoPayload}; +use crate::fixed_rule::algos::shortest_path_dijkstra::dijkstra; +use crate::fixed_rule::{FixedRule, FixedRulePayload}; use crate::data::expr::Expr; use crate::data::symb::Symbol; use crate::data::value::DataValue; @@ -25,10 +25,10 @@ use crate::runtime::temp_store::RegularTempStore; pub(crate) struct KShortestPathYen; -impl AlgoImpl for KShortestPathYen { +impl FixedRule for KShortestPathYen { fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, poison: Poison, ) -> Result<()> { diff --git a/cozo-core/src/algo/mod.rs b/cozo-core/src/fixed_rule/mod.rs similarity index 68% rename from cozo-core/src/algo/mod.rs rename to cozo-core/src/fixed_rule/mod.rs index ac73c311..6c795816 100644 --- a/cozo-core/src/algo/mod.rs +++ b/cozo-core/src/fixed_rule/mod.rs @@ -14,104 +14,73 @@ use miette::{bail, ensure, Diagnostic, Result}; use smartstring::{LazyCompact, SmartString}; use thiserror::Error; -#[cfg(feature = "graph-algo")] -use crate::algo::all_pairs_shortest_path::{BetweennessCentrality, ClosenessCentrality}; -#[cfg(feature = "graph-algo")] -use crate::algo::astar::ShortestPathAStar; -#[cfg(feature = "graph-algo")] -use crate::algo::bfs::Bfs; -use crate::algo::constant::Constant; -use crate::algo::csv::CsvReader; -#[cfg(feature = "graph-algo")] -use crate::algo::degree_centrality::DegreeCentrality; -#[cfg(feature = "graph-algo")] -use crate::algo::dfs::Dfs; -use crate::algo::jlines::JsonReader; -#[cfg(feature = "graph-algo")] -use crate::algo::kruskal::MinimumSpanningForestKruskal; -#[cfg(feature = "graph-algo")] -use crate::algo::label_propagation::LabelPropagation; -#[cfg(feature = "graph-algo")] -use crate::algo::louvain::CommunityDetectionLouvain; -#[cfg(feature = "graph-algo")] -use crate::algo::pagerank::PageRank; -#[cfg(feature = "graph-algo")] -use crate::algo::prim::MinimumSpanningTreePrim; -#[cfg(feature = "graph-algo")] -use crate::algo::random_walk::RandomWalk; -use crate::algo::reorder_sort::ReorderSort; -#[cfg(feature = "graph-algo")] -use crate::algo::shortest_path_dijkstra::ShortestPathDijkstra; -#[cfg(feature = "graph-algo")] -use crate::algo::strongly_connected_components::StronglyConnectedComponent; -#[cfg(feature = "graph-algo")] -use crate::algo::top_sort::TopSort; -#[cfg(feature = "graph-algo")] -use crate::algo::triangles::ClusteringCoefficients; -#[cfg(feature = "graph-algo")] -use crate::algo::yen::KShortestPathYen; use crate::data::expr::Expr; use crate::data::program::{ - AlgoOptionNotFoundError, MagicAlgoApply, MagicAlgoRuleArg, MagicSymbol, WrongAlgoOptionError, + FixedRuleOptionNotFoundError, MagicFixedRuleApply, MagicFixedRuleRuleArg, MagicSymbol, + WrongFixedRuleOptionError, }; use crate::data::symb::Symbol; use crate::data::tuple::TupleIter; use crate::data::value::DataValue; -use crate::parse::SourceSpan; -use crate::runtime::db::Poison; -use crate::runtime::temp_store::{EpochStore, RegularTempStore}; -use crate::runtime::transact::SessionTx; - #[cfg(feature = "graph-algo")] -pub(crate) mod all_pairs_shortest_path; +use crate::fixed_rule::algos::all_pairs_shortest_path::{ + BetweennessCentrality, ClosenessCentrality, +}; #[cfg(feature = "graph-algo")] -pub(crate) mod astar; +use crate::fixed_rule::algos::astar::ShortestPathAStar; #[cfg(feature = "graph-algo")] -pub(crate) mod bfs; -pub(crate) mod constant; -pub(crate) mod csv; +use crate::fixed_rule::algos::bfs::Bfs; #[cfg(feature = "graph-algo")] -pub(crate) mod degree_centrality; +use crate::fixed_rule::algos::degree_centrality::DegreeCentrality; #[cfg(feature = "graph-algo")] -pub(crate) mod dfs; -pub(crate) mod jlines; +use crate::fixed_rule::algos::dfs::Dfs; #[cfg(feature = "graph-algo")] -pub(crate) mod kruskal; +use crate::fixed_rule::algos::kruskal::MinimumSpanningForestKruskal; #[cfg(feature = "graph-algo")] -pub(crate) mod label_propagation; +use crate::fixed_rule::algos::label_propagation::LabelPropagation; #[cfg(feature = "graph-algo")] -pub(crate) mod louvain; +use crate::fixed_rule::algos::louvain::CommunityDetectionLouvain; #[cfg(feature = "graph-algo")] -pub(crate) mod pagerank; +use crate::fixed_rule::algos::pagerank::PageRank; #[cfg(feature = "graph-algo")] -pub(crate) mod prim; +use crate::fixed_rule::algos::prim::MinimumSpanningTreePrim; #[cfg(feature = "graph-algo")] -pub(crate) mod random_walk; -pub(crate) mod reorder_sort; +use crate::fixed_rule::algos::shortest_path_dijkstra::ShortestPathDijkstra; #[cfg(feature = "graph-algo")] -pub(crate) mod shortest_path_dijkstra; -pub(crate) mod strongly_connected_components; +use crate::fixed_rule::algos::strongly_connected_components::StronglyConnectedComponent; #[cfg(feature = "graph-algo")] -pub(crate) mod top_sort; +use crate::fixed_rule::algos::top_sort::TopSort; #[cfg(feature = "graph-algo")] -pub(crate) mod triangles; +use crate::fixed_rule::algos::triangles::ClusteringCoefficients; #[cfg(feature = "graph-algo")] -pub(crate) mod yen; +use crate::fixed_rule::algos::yen::KShortestPathYen; +use crate::fixed_rule::utilities::constant::Constant; +use crate::fixed_rule::utilities::csv::CsvReader; +use crate::fixed_rule::utilities::jlines::JsonReader; +use crate::fixed_rule::utilities::random_walk::RandomWalk; +use crate::fixed_rule::utilities::reorder_sort::ReorderSort; +use crate::parse::SourceSpan; +use crate::runtime::db::Poison; +use crate::runtime::temp_store::{EpochStore, RegularTempStore}; +use crate::runtime::transact::SessionTx; -pub struct AlgoPayload<'a, 'b> { - pub(crate) manifest: &'a MagicAlgoApply, +pub(crate) mod algos; +pub(crate) mod utilities; + +pub struct FixedRulePayload<'a, 'b> { + pub(crate) manifest: &'a MagicFixedRuleApply, pub(crate) stores: &'a BTreeMap, pub(crate) tx: &'a SessionTx<'b>, } #[derive(Copy, Clone)] -pub struct AlgoInputRelation<'a, 'b> { - arg_manifest: &'a MagicAlgoRuleArg, +pub struct FixedRuleInputRelation<'a, 'b> { + arg_manifest: &'a MagicFixedRuleRuleArg, stores: &'a BTreeMap, tx: &'a SessionTx<'b>, } -impl<'a, 'b> AlgoInputRelation<'a, 'b> { +impl<'a, 'b> FixedRuleInputRelation<'a, 'b> { pub fn arity(&self) -> Result { self.arg_manifest.arity(self.tx, self.stores) } @@ -133,10 +102,34 @@ impl<'a, 'b> AlgoInputRelation<'a, 'b> { self.arg_manifest.get_binding_map(offset) } pub fn iter(&self) -> Result> { - self.arg_manifest.iter(self.tx, self.stores) + Ok(match &self.arg_manifest { + MagicFixedRuleRuleArg::InMem { name, .. } => { + let store = self.stores.get(name).ok_or_else(|| { + RuleNotFoundError(name.symbol().to_string(), name.symbol().span) + })?; + Box::new(store.all_iter().map(|t| Ok(t.into_tuple()))) + } + MagicFixedRuleRuleArg::Stored { name, .. } => { + let relation = self.tx.get_relation(name, false)?; + Box::new(relation.scan_all(self.tx)) + } + }) } pub fn prefix_iter(&self, prefix: &DataValue) -> Result> { - self.arg_manifest.prefix_iter(prefix, self.tx, self.stores) + Ok(match self.arg_manifest { + MagicFixedRuleRuleArg::InMem { name, .. } => { + let store = self.stores.get(name).ok_or_else(|| { + RuleNotFoundError(name.symbol().to_string(), name.symbol().span) + })?; + let t = vec![prefix.clone()]; + Box::new(store.prefix_iter(&t).map(|t| Ok(t.into_tuple()))) + } + MagicFixedRuleRuleArg::Stored { name, .. } => { + let relation = self.tx.get_relation(name, false)?; + let t = vec![prefix.clone()]; + Box::new(relation.scan_prefix(self.tx, &t)) + } + }) } pub fn span(&self) -> SourceSpan { self.arg_manifest.span() @@ -145,8 +138,38 @@ impl<'a, 'b> AlgoInputRelation<'a, 'b> { &self, undirected: bool, ) -> Result<(Vec>, Vec, BTreeMap)> { - self.arg_manifest - .convert_edge_to_graph(undirected, self.tx, self.stores) + let mut graph: Vec> = vec![]; + let mut indices: Vec = vec![]; + let mut inv_indices: BTreeMap = Default::default(); + + for tuple in self.iter()? { + let mut tuple = tuple?.into_iter(); + let from = tuple.next().ok_or_else(|| NotAnEdgeError(self.span()))?; + let to = tuple.next().ok_or_else(|| NotAnEdgeError(self.span()))?; + let from_idx = if let Some(idx) = inv_indices.get(&from) { + *idx + } else { + inv_indices.insert(from.clone(), graph.len()); + indices.push(from.clone()); + graph.push(vec![]); + graph.len() - 1 + }; + let to_idx = if let Some(idx) = inv_indices.get(&to) { + *idx + } else { + inv_indices.insert(to.clone(), graph.len()); + indices.push(to.clone()); + graph.push(vec![]); + graph.len() - 1 + }; + let from_target = graph.get_mut(from_idx).unwrap(); + from_target.push(to_idx); + if undirected { + let to_target = graph.get_mut(to_idx).unwrap(); + to_target.push(from_idx); + } + } + Ok((graph, indices, inv_indices)) } pub fn convert_edge_to_weighted_graph( &self, @@ -158,26 +181,95 @@ impl<'a, 'b> AlgoInputRelation<'a, 'b> { BTreeMap, bool, )> { - self.arg_manifest.convert_edge_to_weighted_graph( - undirected, - allow_negative_edges, - self.tx, - self.stores, - ) + let mut graph: Vec> = vec![]; + let mut indices: Vec = vec![]; + let mut inv_indices: BTreeMap = Default::default(); + let mut has_neg_edge = false; + + for tuple in self.iter()? { + let mut tuple = tuple?.into_iter(); + let from = tuple.next().ok_or_else(|| NotAnEdgeError(self.span()))?; + let to = tuple.next().ok_or_else(|| NotAnEdgeError(self.span()))?; + let weight = match tuple.next() { + None => 1.0, + Some(d) => match d.get_float() { + Some(f) => { + ensure!( + f.is_finite(), + BadEdgeWeightError( + d, + self.arg_manifest + .bindings() + .get(2) + .map(|s| s.span) + .unwrap_or_else(|| self.span()) + ) + ); + if f < 0. { + if !allow_negative_edges { + bail!(BadEdgeWeightError( + d, + self.arg_manifest + .bindings() + .get(2) + .map(|s| s.span) + .unwrap_or_else(|| self.span()) + )); + } + has_neg_edge = true; + } + f + } + None => { + bail!(BadEdgeWeightError( + d, + self.arg_manifest + .bindings() + .get(2) + .map(|s| s.span) + .unwrap_or_else(|| self.span()) + )) + } + }, + }; + let from_idx = if let Some(idx) = inv_indices.get(&from) { + *idx + } else { + inv_indices.insert(from.clone(), graph.len()); + indices.push(from.clone()); + graph.push(vec![]); + graph.len() - 1 + }; + let to_idx = if let Some(idx) = inv_indices.get(&to) { + *idx + } else { + inv_indices.insert(to.clone(), graph.len()); + indices.push(to.clone()); + graph.push(vec![]); + graph.len() - 1 + }; + let from_target = graph.get_mut(from_idx).unwrap(); + from_target.push((to_idx, weight)); + if undirected { + let to_target = graph.get_mut(to_idx).unwrap(); + to_target.push((from_idx, weight)); + } + } + Ok((graph, indices, inv_indices, has_neg_edge)) } } -impl<'a, 'b> AlgoPayload<'a, 'b> { - pub fn get_input(&self, idx: usize) -> Result> { +impl<'a, 'b> FixedRulePayload<'a, 'b> { + pub fn get_input(&self, idx: usize) -> Result> { let arg_manifest = self.manifest.relation(idx)?; - Ok(AlgoInputRelation { + Ok(FixedRuleInputRelation { arg_manifest, stores: self.stores, tx: self.tx, }) } pub fn name(&self) -> &str { - &self.manifest.algo.name + &self.manifest.fixed_handle.name } pub fn span(&self) -> SourceSpan { self.manifest.span @@ -187,10 +279,10 @@ impl<'a, 'b> AlgoPayload<'a, 'b> { Some(ex) => Ok(ex.clone()), None => match default { Some(ex) => Ok(ex), - None => Err(AlgoOptionNotFoundError { + None => Err(FixedRuleOptionNotFoundError { name: name.to_string(), span: self.manifest.span, - algo_name: self.manifest.algo.name.to_string(), + rule_name: self.manifest.fixed_handle.name.to_string(), } .into()), }, @@ -205,19 +297,19 @@ impl<'a, 'b> AlgoPayload<'a, 'b> { match self.manifest.options.get(name) { Some(ex) => match ex.clone().eval_to_const()? { DataValue::Str(s) => Ok(s), - _ => Err(WrongAlgoOptionError { + _ => Err(WrongFixedRuleOptionError { name: name.to_string(), span: ex.span(), - algo_name: self.manifest.algo.name.to_string(), + rule_name: self.manifest.fixed_handle.name.to_string(), help: "a string is required".to_string(), } .into()), }, None => match default { - None => Err(AlgoOptionNotFoundError { + None => Err(FixedRuleOptionNotFoundError { name: name.to_string(), span: self.manifest.span, - algo_name: self.manifest.algo.name.to_string(), + rule_name: self.manifest.fixed_handle.name.to_string(), } .into()), Some(s) => Ok(SmartString::from(s)), @@ -232,36 +324,36 @@ impl<'a, 'b> AlgoPayload<'a, 'b> { Some(i) => { ensure!( i > 0, - WrongAlgoOptionError { + WrongFixedRuleOptionError { name: name.to_string(), span: v.span(), - algo_name: self.manifest.algo.name.to_string(), + rule_name: self.manifest.fixed_handle.name.to_string(), help: "a positive integer is required".to_string(), } ); Ok(i as usize) } - None => Err(AlgoOptionNotFoundError { + None => Err(FixedRuleOptionNotFoundError { name: name.to_string(), span: self.span(), - algo_name: self.manifest.algo.name.to_string(), + rule_name: self.manifest.fixed_handle.name.to_string(), } .into()), }, - _ => Err(WrongAlgoOptionError { + _ => Err(WrongFixedRuleOptionError { name: name.to_string(), span: v.span(), - algo_name: self.manifest.algo.name.to_string(), + rule_name: self.manifest.fixed_handle.name.to_string(), help: "a positive integer is required".to_string(), } .into()), }, None => match default { Some(v) => Ok(v), - None => Err(AlgoOptionNotFoundError { + None => Err(FixedRuleOptionNotFoundError { name: name.to_string(), span: self.manifest.span, - algo_name: self.manifest.algo.name.to_string(), + rule_name: self.manifest.fixed_handle.name.to_string(), } .into()), }, @@ -274,36 +366,36 @@ impl<'a, 'b> AlgoPayload<'a, 'b> { Some(i) => { ensure!( i >= 0, - WrongAlgoOptionError { + WrongFixedRuleOptionError { name: name.to_string(), span: v.span(), - algo_name: self.manifest.algo.name.to_string(), + rule_name: self.manifest.fixed_handle.name.to_string(), help: "a non-negative integer is required".to_string(), } ); Ok(i as usize) } - None => Err(AlgoOptionNotFoundError { + None => Err(FixedRuleOptionNotFoundError { name: name.to_string(), span: self.manifest.span, - algo_name: self.manifest.algo.name.to_string(), + rule_name: self.manifest.fixed_handle.name.to_string(), } .into()), }, - _ => Err(WrongAlgoOptionError { + _ => Err(WrongFixedRuleOptionError { name: name.to_string(), span: v.span(), - algo_name: self.manifest.algo.name.to_string(), + rule_name: self.manifest.fixed_handle.name.to_string(), help: "a non-negative integer is required".to_string(), } .into()), }, None => match default { Some(v) => Ok(v), - None => Err(AlgoOptionNotFoundError { + None => Err(FixedRuleOptionNotFoundError { name: name.to_string(), span: self.manifest.span, - algo_name: self.manifest.algo.name.to_string(), + rule_name: self.manifest.fixed_handle.name.to_string(), } .into()), }, @@ -316,29 +408,29 @@ impl<'a, 'b> AlgoPayload<'a, 'b> { let f = n.get_float(); ensure!( (0. ..=1.).contains(&f), - WrongAlgoOptionError { + WrongFixedRuleOptionError { name: name.to_string(), span: v.span(), - algo_name: self.manifest.algo.name.to_string(), + rule_name: self.manifest.fixed_handle.name.to_string(), help: "a number between 0. and 1. is required".to_string(), } ); Ok(f) } - _ => Err(WrongAlgoOptionError { + _ => Err(WrongFixedRuleOptionError { name: name.to_string(), span: v.span(), - algo_name: self.manifest.algo.name.to_string(), + rule_name: self.manifest.fixed_handle.name.to_string(), help: "a number between 0. and 1. is required".to_string(), } .into()), }, None => match default { Some(v) => Ok(v), - None => Err(AlgoOptionNotFoundError { + None => Err(FixedRuleOptionNotFoundError { name: name.to_string(), span: self.manifest.span, - algo_name: self.manifest.algo.name.to_string(), + rule_name: self.manifest.fixed_handle.name.to_string(), } .into()), }, @@ -348,20 +440,20 @@ impl<'a, 'b> AlgoPayload<'a, 'b> { match self.manifest.options.get(name) { Some(v) => match v.clone().eval_to_const() { Ok(DataValue::Bool(b)) => Ok(b), - _ => Err(WrongAlgoOptionError { + _ => Err(WrongFixedRuleOptionError { name: name.to_string(), span: v.span(), - algo_name: self.manifest.algo.name.to_string(), + rule_name: self.manifest.fixed_handle.name.to_string(), help: "a boolean value is required".to_string(), } .into()), }, None => match default { Some(v) => Ok(v), - None => Err(AlgoOptionNotFoundError { + None => Err(FixedRuleOptionNotFoundError { name: name.to_string(), span: self.manifest.span, - algo_name: self.manifest.algo.name.to_string(), + rule_name: self.manifest.fixed_handle.name.to_string(), } .into()), }, @@ -370,7 +462,7 @@ impl<'a, 'b> AlgoPayload<'a, 'b> { } /// Trait for an implementation of an algorithm or a utility -pub trait AlgoImpl: Send + Sync { +pub trait FixedRule: Send + Sync { /// Called to initialize the options given. /// Will always be called once, before anything else. /// You can mutate the options if you need to. @@ -395,7 +487,7 @@ pub trait AlgoImpl: Send + Sync { /// for user-initiated termination. fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &'_ mut RegularTempStore, poison: Poison, ) -> Result<()>; @@ -411,141 +503,141 @@ pub(crate) struct CannotDetermineArity( ); #[derive(Clone, Debug)] -pub(crate) struct AlgoHandle { +pub(crate) struct FixedRuleHandle { pub(crate) name: Symbol, } lazy_static! { - pub(crate) static ref DEFAULT_ALGOS: Arc>>> = { + pub(crate) static ref DEFAULT_FIXED_RULES: Arc>>> = { Arc::new(BTreeMap::from([ #[cfg(feature = "graph-algo")] ( "ClusteringCoefficients".to_string(), - Arc::>::new(Box::new(ClusteringCoefficients)), + Arc::>::new(Box::new(ClusteringCoefficients)), ), #[cfg(feature = "graph-algo")] ( "DegreeCentrality".to_string(), - Arc::>::new(Box::new(DegreeCentrality)), + Arc::>::new(Box::new(DegreeCentrality)), ), #[cfg(feature = "graph-algo")] ( "ClosenessCentrality".to_string(), - Arc::>::new(Box::new(ClosenessCentrality)), + Arc::>::new(Box::new(ClosenessCentrality)), ), #[cfg(feature = "graph-algo")] ( "BetweennessCentrality".to_string(), - Arc::>::new(Box::new(BetweennessCentrality)), + Arc::>::new(Box::new(BetweennessCentrality)), ), #[cfg(feature = "graph-algo")] ( "DepthFirstSearch".to_string(), - Arc::>::new(Box::new(Dfs)), + Arc::>::new(Box::new(Dfs)), ), #[cfg(feature = "graph-algo")] ( "DFS".to_string(), - Arc::>::new(Box::new(Dfs)), + Arc::>::new(Box::new(Dfs)), ), #[cfg(feature = "graph-algo")] ( "BreadthFirstSearch".to_string(), - Arc::>::new(Box::new(Bfs)), + Arc::>::new(Box::new(Bfs)), ), #[cfg(feature = "graph-algo")] ( "BFS".to_string(), - Arc::>::new(Box::new(Bfs)), + Arc::>::new(Box::new(Bfs)), ), #[cfg(feature = "graph-algo")] ( "ShortestPathDijkstra".to_string(), - Arc::>::new(Box::new(ShortestPathDijkstra)), + Arc::>::new(Box::new(ShortestPathDijkstra)), ), #[cfg(feature = "graph-algo")] ( "ShortestPathAStar".to_string(), - Arc::>::new(Box::new(ShortestPathAStar)), + Arc::>::new(Box::new(ShortestPathAStar)), ), #[cfg(feature = "graph-algo")] ( "KShortestPathYen".to_string(), - Arc::>::new(Box::new(KShortestPathYen)), + Arc::>::new(Box::new(KShortestPathYen)), ), #[cfg(feature = "graph-algo")] ( "MinimumSpanningTreePrim".to_string(), - Arc::>::new(Box::new(MinimumSpanningTreePrim)), + Arc::>::new(Box::new(MinimumSpanningTreePrim)), ), #[cfg(feature = "graph-algo")] ( "MinimumSpanningForestKruskal".to_string(), - Arc::>::new(Box::new(MinimumSpanningForestKruskal)), + Arc::>::new(Box::new(MinimumSpanningForestKruskal)), ), #[cfg(feature = "graph-algo")] ( "TopSort".to_string(), - Arc::>::new(Box::new(TopSort)), + Arc::>::new(Box::new(TopSort)), ), #[cfg(feature = "graph-algo")] ( "ConnectedComponents".to_string(), - Arc::>::new(Box::new(StronglyConnectedComponent::new(false))), + Arc::>::new(Box::new(StronglyConnectedComponent::new(false))), ), #[cfg(feature = "graph-algo")] ( "StronglyConnectedComponents".to_string(), - Arc::>::new(Box::new(StronglyConnectedComponent::new(true))), + Arc::>::new(Box::new(StronglyConnectedComponent::new(true))), ), #[cfg(feature = "graph-algo")] ( "SCC".to_string(), - Arc::>::new(Box::new(StronglyConnectedComponent::new(true))), + Arc::>::new(Box::new(StronglyConnectedComponent::new(true))), ), #[cfg(feature = "graph-algo")] ( "PageRank".to_string(), - Arc::>::new(Box::new(PageRank)), + Arc::>::new(Box::new(PageRank)), ), #[cfg(feature = "graph-algo")] ( "CommunityDetectionLouvain".to_string(), - Arc::>::new(Box::new(CommunityDetectionLouvain)), + Arc::>::new(Box::new(CommunityDetectionLouvain)), ), #[cfg(feature = "graph-algo")] ( "LabelPropagation".to_string(), - Arc::>::new(Box::new(LabelPropagation)), + Arc::>::new(Box::new(LabelPropagation)), ), #[cfg(feature = "graph-algo")] ( "RandomWalk".to_string(), - Arc::>::new(Box::new(RandomWalk)), + Arc::>::new(Box::new(RandomWalk)), ), ( "ReorderSort".to_string(), - Arc::>::new(Box::new(ReorderSort)), + Arc::>::new(Box::new(ReorderSort)), ), ( "JsonReader".to_string(), - Arc::>::new(Box::new(JsonReader)), + Arc::>::new(Box::new(JsonReader)), ), ( "CsvReader".to_string(), - Arc::>::new(Box::new(CsvReader)), + Arc::>::new(Box::new(CsvReader)), ), ( "Constant".to_string(), - Arc::>::new(Box::new(Constant)), + Arc::>::new(Box::new(Constant)), ), ])) }; } -impl AlgoHandle { +impl FixedRuleHandle { pub(crate) fn new(name: &str, span: SourceSpan) -> Self { - AlgoHandle { + FixedRuleHandle { name: Symbol::new(name, span), } } @@ -602,191 +694,27 @@ pub(crate) struct BadExprValueError( ); #[derive(Error, Diagnostic, Debug)] -#[error("The requested algorithm '{0}' is not found")] -#[diagnostic(code(parser::algo_not_found))] -pub(crate) struct AlgoNotFoundError(pub(crate) String, #[label] pub(crate) SourceSpan); - -impl MagicAlgoRuleArg { - #[allow(dead_code)] - pub(crate) fn convert_edge_to_weighted_graph<'a>( - &'a self, - undirected: bool, - allow_negative_edges: bool, - tx: &'a SessionTx<'_>, - stores: &'a BTreeMap, - ) -> Result<( - Vec>, - Vec, - BTreeMap, - bool, - )> { - let mut graph: Vec> = vec![]; - let mut indices: Vec = vec![]; - let mut inv_indices: BTreeMap = Default::default(); - let mut has_neg_edge = false; +#[error("The requested fixed rule '{0}' is not found")] +#[diagnostic(code(parser::fixed_rule_not_found))] +pub(crate) struct FixedRuleNotFoundError(pub(crate) String, #[label] pub(crate) SourceSpan); - for tuple in self.iter(tx, stores)? { - let mut tuple = tuple?.into_iter(); - let from = tuple.next().ok_or_else(|| NotAnEdgeError(self.span()))?; - let to = tuple.next().ok_or_else(|| NotAnEdgeError(self.span()))?; - let weight = match tuple.next() { - None => 1.0, - Some(d) => match d.get_float() { - Some(f) => { - ensure!( - f.is_finite(), - BadEdgeWeightError( - d, - self.bindings() - .get(2) - .map(|s| s.span) - .unwrap_or_else(|| self.span()) - ) - ); - if f < 0. { - if !allow_negative_edges { - bail!(BadEdgeWeightError( - d, - self.bindings() - .get(2) - .map(|s| s.span) - .unwrap_or_else(|| self.span()) - )); - } - has_neg_edge = true; - } - f - } - None => { - bail!(BadEdgeWeightError( - d, - self.bindings() - .get(2) - .map(|s| s.span) - .unwrap_or_else(|| self.span()) - )) - } - }, - }; - let from_idx = if let Some(idx) = inv_indices.get(&from) { - *idx - } else { - inv_indices.insert(from.clone(), graph.len()); - indices.push(from.clone()); - graph.push(vec![]); - graph.len() - 1 - }; - let to_idx = if let Some(idx) = inv_indices.get(&to) { - *idx - } else { - inv_indices.insert(to.clone(), graph.len()); - indices.push(to.clone()); - graph.push(vec![]); - graph.len() - 1 - }; - let from_target = graph.get_mut(from_idx).unwrap(); - from_target.push((to_idx, weight)); - if undirected { - let to_target = graph.get_mut(to_idx).unwrap(); - to_target.push((from_idx, weight)); - } - } - Ok((graph, indices, inv_indices, has_neg_edge)) - } - pub(crate) fn convert_edge_to_graph<'a>( - &'a self, - undirected: bool, - tx: &'a SessionTx<'_>, - stores: &'a BTreeMap, - ) -> Result<(Vec>, Vec, BTreeMap)> { - let mut graph: Vec> = vec![]; - let mut indices: Vec = vec![]; - let mut inv_indices: BTreeMap = Default::default(); - - for tuple in self.iter(tx, stores)? { - let mut tuple = tuple?.into_iter(); - let from = tuple.next().ok_or_else(|| NotAnEdgeError(self.span()))?; - let to = tuple.next().ok_or_else(|| NotAnEdgeError(self.span()))?; - let from_idx = if let Some(idx) = inv_indices.get(&from) { - *idx - } else { - inv_indices.insert(from.clone(), graph.len()); - indices.push(from.clone()); - graph.push(vec![]); - graph.len() - 1 - }; - let to_idx = if let Some(idx) = inv_indices.get(&to) { - *idx - } else { - inv_indices.insert(to.clone(), graph.len()); - indices.push(to.clone()); - graph.push(vec![]); - graph.len() - 1 - }; - let from_target = graph.get_mut(from_idx).unwrap(); - from_target.push(to_idx); - if undirected { - let to_target = graph.get_mut(to_idx).unwrap(); - to_target.push(from_idx); - } - } - Ok((graph, indices, inv_indices)) - } - pub(crate) fn prefix_iter<'a>( - &'a self, - prefix: &DataValue, - tx: &'a SessionTx<'_>, - stores: &'a BTreeMap, - ) -> Result> { - Ok(match self { - MagicAlgoRuleArg::InMem { name, .. } => { - let store = stores.get(name).ok_or_else(|| { - RuleNotFoundError(name.symbol().to_string(), name.symbol().span) - })?; - let t = vec![prefix.clone()]; - Box::new(store.prefix_iter(&t).map(|t| Ok(t.into_tuple()))) - } - MagicAlgoRuleArg::Stored { name, .. } => { - let relation = tx.get_relation(name, false)?; - let t = vec![prefix.clone()]; - Box::new(relation.scan_prefix(tx, &t)) - } - }) - } +impl MagicFixedRuleRuleArg { pub(crate) fn arity( &self, tx: &SessionTx<'_>, stores: &BTreeMap, ) -> Result { Ok(match self { - MagicAlgoRuleArg::InMem { name, .. } => { + MagicFixedRuleRuleArg::InMem { name, .. } => { let store = stores.get(name).ok_or_else(|| { RuleNotFoundError(name.symbol().to_string(), name.symbol().span) })?; store.arity } - MagicAlgoRuleArg::Stored { name, .. } => { + MagicFixedRuleRuleArg::Stored { name, .. } => { let handle = tx.get_relation(name, false)?; handle.arity() } }) } - pub(crate) fn iter<'a>( - &'a self, - tx: &'a SessionTx<'_>, - stores: &'a BTreeMap, - ) -> Result> { - Ok(match self { - MagicAlgoRuleArg::InMem { name, .. } => { - let store = stores.get(name).ok_or_else(|| { - RuleNotFoundError(name.symbol().to_string(), name.symbol().span) - })?; - Box::new(store.all_iter().map(|t| Ok(t.into_tuple()))) - } - MagicAlgoRuleArg::Stored { name, .. } => { - let relation = tx.get_relation(name, false)?; - Box::new(relation.scan_all(tx)) - } - }) - } } diff --git a/cozo-core/src/algo/constant.rs b/cozo-core/src/fixed_rule/utilities/constant.rs similarity index 91% rename from cozo-core/src/algo/constant.rs rename to cozo-core/src/fixed_rule/utilities/constant.rs index 9971f3a2..5c104bd1 100644 --- a/cozo-core/src/algo/constant.rs +++ b/cozo-core/src/fixed_rule/utilities/constant.rs @@ -12,9 +12,9 @@ use miette::{bail, ensure, Diagnostic, Result}; use smartstring::{LazyCompact, SmartString}; use thiserror::Error; -use crate::algo::{AlgoImpl, AlgoPayload}; +use crate::fixed_rule::{FixedRule, FixedRulePayload}; use crate::data::expr::Expr; -use crate::data::program::WrongAlgoOptionError; +use crate::data::program::WrongFixedRuleOptionError; use crate::data::symb::Symbol; use crate::data::value::DataValue; use crate::parse::SourceSpan; @@ -23,10 +23,10 @@ use crate::runtime::temp_store::RegularTempStore; pub(crate) struct Constant; -impl AlgoImpl for Constant { +impl FixedRule for Constant { fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, _poison: Poison, ) -> Result<()> { @@ -76,18 +76,18 @@ impl AlgoImpl for Constant { options: &mut BTreeMap, Expr>, span: SourceSpan, ) -> Result<()> { - let data = options.get("data").ok_or_else(|| WrongAlgoOptionError { + let data = options.get("data").ok_or_else(|| WrongFixedRuleOptionError { name: "data".to_string(), span: Default::default(), - algo_name: "Constant".to_string(), + rule_name: "Constant".to_string(), help: "a list of lists is required".to_string(), })?; let data = match data.clone().eval_to_const()? { DataValue::List(l) => l, - _ => bail!(WrongAlgoOptionError { + _ => bail!(WrongFixedRuleOptionError { name: "data".to_string(), span: Default::default(), - algo_name: "Constant".to_string(), + rule_name: "Constant".to_string(), help: "a list of lists is required".to_string(), }), }; diff --git a/cozo-core/src/algo/csv.rs b/cozo-core/src/fixed_rule/utilities/csv.rs similarity index 92% rename from cozo-core/src/algo/csv.rs rename to cozo-core/src/fixed_rule/utilities/csv.rs index 5dca59ee..a07e85e2 100644 --- a/cozo-core/src/algo/csv.rs +++ b/cozo-core/src/fixed_rule/utilities/csv.rs @@ -13,11 +13,11 @@ use miette::{bail, ensure, IntoDiagnostic, Result}; use smartstring::{LazyCompact, SmartString}; #[cfg(feature = "requests")] -use crate::algo::jlines::get_file_content_from_url; -use crate::algo::{AlgoImpl, AlgoPayload, CannotDetermineArity}; +use crate::fixed_rule::utilities::jlines::get_file_content_from_url; +use crate::fixed_rule::{FixedRule, FixedRulePayload, CannotDetermineArity}; use crate::data::expr::Expr; use crate::data::functions::{op_to_float, op_to_uuid}; -use crate::data::program::{AlgoOptionNotFoundError, WrongAlgoOptionError}; +use crate::data::program::{FixedRuleOptionNotFoundError, WrongFixedRuleOptionError}; use crate::data::relation::{ColType, NullableColType}; use crate::data::symb::Symbol; use crate::data::value::DataValue; @@ -27,10 +27,10 @@ use crate::runtime::temp_store::RegularTempStore; pub(crate) struct CsvReader; -impl AlgoImpl for CsvReader { +impl FixedRule for CsvReader { fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, _poison: Poison, ) -> Result<()> { @@ -38,10 +38,10 @@ impl AlgoImpl for CsvReader { let delimiter = delimiter.as_bytes(); ensure!( delimiter.len() == 1, - WrongAlgoOptionError { + WrongFixedRuleOptionError { name: "delimiter".to_string(), span: payload.span(), - algo_name: "CsvReader".to_string(), + rule_name: "CsvReader".to_string(), help: "'delimiter' must be a single-byte string".to_string() } ); @@ -63,10 +63,10 @@ impl AlgoImpl for CsvReader { let mut types = vec![]; for type_str in types_opts.get_list().unwrap() { let type_str = type_str.get_string().unwrap(); - let typ = parse_type(type_str).map_err(|e| WrongAlgoOptionError { + let typ = parse_type(type_str).map_err(|e| WrongFixedRuleOptionError { name: "types".to_string(), span: payload.span(), - algo_name: "CsvReader".to_string(), + rule_name: "CsvReader".to_string(), help: e.to_string(), })?; types.push(typ); @@ -197,10 +197,10 @@ impl AlgoImpl for CsvReader { }; let columns = options .get("types") - .ok_or_else(|| AlgoOptionNotFoundError { + .ok_or_else(|| FixedRuleOptionNotFoundError { name: "types".to_string(), span, - algo_name: "CsvReader".to_string(), + rule_name: "CsvReader".to_string(), })?; let columns = columns.clone().eval_to_const()?; if let Some(l) = columns.get_list() { diff --git a/cozo-core/src/algo/jlines.rs b/cozo-core/src/fixed_rule/utilities/jlines.rs similarity index 97% rename from cozo-core/src/algo/jlines.rs rename to cozo-core/src/fixed_rule/utilities/jlines.rs index 584d4317..22821ab2 100644 --- a/cozo-core/src/algo/jlines.rs +++ b/cozo-core/src/fixed_rule/utilities/jlines.rs @@ -20,7 +20,7 @@ use minreq::Response; use smartstring::{LazyCompact, SmartString}; use thiserror::Error; -use crate::algo::{AlgoImpl, AlgoPayload, CannotDetermineArity}; +use crate::fixed_rule::{FixedRule, FixedRulePayload, CannotDetermineArity}; use crate::data::expr::Expr; use crate::data::json::JsonValue; use crate::data::symb::Symbol; @@ -31,10 +31,10 @@ use crate::runtime::temp_store::RegularTempStore; pub(crate) struct JsonReader; -impl AlgoImpl for JsonReader { +impl FixedRule for JsonReader { fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, _poison: Poison, ) -> Result<()> { diff --git a/cozo-core/src/fixed_rule/utilities/mod.rs b/cozo-core/src/fixed_rule/utilities/mod.rs new file mode 100644 index 00000000..a441748c --- /dev/null +++ b/cozo-core/src/fixed_rule/utilities/mod.rs @@ -0,0 +1,13 @@ +/* + * Copyright 2022, The Cozo Project Authors. + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +pub(crate) mod constant; +pub(crate) mod csv; +pub(crate) mod jlines; +pub(crate) mod random_walk; +pub(crate) mod reorder_sort; diff --git a/cozo-core/src/algo/random_walk.rs b/cozo-core/src/fixed_rule/utilities/random_walk.rs similarity index 96% rename from cozo-core/src/algo/random_walk.rs rename to cozo-core/src/fixed_rule/utilities/random_walk.rs index 2917c2ed..95cd3c77 100644 --- a/cozo-core/src/algo/random_walk.rs +++ b/cozo-core/src/fixed_rule/utilities/random_walk.rs @@ -14,7 +14,7 @@ use rand::distributions::WeightedIndex; use rand::prelude::*; use smartstring::{LazyCompact, SmartString}; -use crate::algo::{AlgoImpl, AlgoPayload, BadExprValueError, NodeNotFoundError}; +use crate::fixed_rule::{FixedRule, FixedRulePayload, BadExprValueError, NodeNotFoundError}; use crate::data::expr::Expr; use crate::data::symb::Symbol; use crate::data::value::DataValue; @@ -24,10 +24,10 @@ use crate::runtime::temp_store::RegularTempStore; pub(crate) struct RandomWalk; -impl AlgoImpl for RandomWalk { +impl FixedRule for RandomWalk { fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, poison: Poison, ) -> Result<()> { diff --git a/cozo-core/src/algo/reorder_sort.rs b/cozo-core/src/fixed_rule/utilities/reorder_sort.rs similarity index 93% rename from cozo-core/src/algo/reorder_sort.rs rename to cozo-core/src/fixed_rule/utilities/reorder_sort.rs index 036a555f..6b920520 100644 --- a/cozo-core/src/algo/reorder_sort.rs +++ b/cozo-core/src/fixed_rule/utilities/reorder_sort.rs @@ -12,22 +12,22 @@ use itertools::Itertools; use miette::{bail, Result}; use smartstring::{LazyCompact, SmartString}; -use crate::algo::{AlgoImpl, AlgoPayload, CannotDetermineArity}; use crate::data::expr::Expr; use crate::data::functions::OP_LIST; -use crate::data::program::WrongAlgoOptionError; +use crate::data::program::WrongFixedRuleOptionError; use crate::data::symb::Symbol; use crate::data::value::DataValue; +use crate::fixed_rule::{FixedRule, FixedRulePayload, CannotDetermineArity}; use crate::parse::SourceSpan; use crate::runtime::db::Poison; use crate::runtime::temp_store::RegularTempStore; pub(crate) struct ReorderSort; -impl AlgoImpl for ReorderSort { +impl FixedRule for ReorderSort { fn run( &self, - payload: AlgoPayload<'_, '_>, + payload: FixedRulePayload<'_, '_>, out: &mut RegularTempStore, poison: Poison, ) -> Result<()> { @@ -46,10 +46,10 @@ impl AlgoImpl for ReorderSort { .collect_vec(), Expr::Apply { op, args, .. } if *op == OP_LIST => args.to_vec(), _ => { - bail!(WrongAlgoOptionError { + bail!(WrongFixedRuleOptionError { name: "out".to_string(), span: payload.span(), - algo_name: payload.name().to_string(), + rule_name: payload.name().to_string(), help: "This option must evaluate to a list".to_string() }) } diff --git a/cozo-core/src/lib.rs b/cozo-core/src/lib.rs index 4eabefbb..488f9ca8 100644 --- a/cozo-core/src/lib.rs +++ b/cozo-core/src/lib.rs @@ -62,17 +62,17 @@ pub use storage::sqlite::{new_cozo_sqlite, SqliteStorage}; pub use storage::tikv::{new_cozo_tikv, TiKvStorage}; pub use storage::{Storage, StoreTx}; pub use runtime::temp_store::RegularTempStore; -pub use algo::AlgoImpl; +pub use fixed_rule::FixedRule; use crate::data::json::JsonValue; -pub(crate) mod algo; pub(crate) mod data; pub(crate) mod parse; pub(crate) mod query; pub(crate) mod runtime; pub(crate) mod storage; pub(crate) mod utils; +pub(crate) mod fixed_rule; #[derive(Clone)] /// A dispatcher for concrete storage implementations, wrapping [Db]. This is done so that diff --git a/cozo-core/src/parse/mod.rs b/cozo-core/src/parse/mod.rs index f689e015..21b20794 100644 --- a/cozo-core/src/parse/mod.rs +++ b/cozo-core/src/parse/mod.rs @@ -21,7 +21,7 @@ use crate::data::value::DataValue; use crate::parse::query::parse_query; use crate::parse::schema::parse_nullable_type; use crate::parse::sys::{parse_sys, SysOp}; -use crate::AlgoImpl; +use crate::FixedRule; pub(crate) mod expr; pub(crate) mod query; @@ -106,7 +106,7 @@ pub(crate) fn parse_type(src: &str) -> Result { pub(crate) fn parse_script( src: &str, param_pool: &BTreeMap, - algorithms: &BTreeMap>>, + algorithms: &BTreeMap>>, ) -> Result { let parsed = CozoScriptParser::parse(Rule::script, src) .map_err(|err| { diff --git a/cozo-core/src/parse/query.rs b/cozo-core/src/parse/query.rs index 62ba62c5..594e4e73 100644 --- a/cozo-core/src/parse/query.rs +++ b/cozo-core/src/parse/query.rs @@ -19,23 +19,23 @@ use miette::{bail, ensure, Diagnostic, LabeledSpan, Report, Result}; use smartstring::{LazyCompact, SmartString}; use thiserror::Error; -use crate::algo::constant::Constant; -use crate::algo::{AlgoHandle, AlgoNotFoundError}; use crate::data::aggr::{parse_aggr, Aggregation}; use crate::data::expr::Expr; use crate::data::program::{ - AlgoApply, AlgoRuleArg, InputAtom, InputInlineRule, InputInlineRulesOrAlgo, + FixedRuleApply, FixedRuleArg, InputAtom, InputInlineRule, InputInlineRulesOrFixed, InputNamedFieldRelationApplyAtom, InputProgram, InputRelationApplyAtom, InputRuleApplyAtom, QueryAssertion, QueryOutOptions, RelationOp, SortDir, Unification, }; use crate::data::relation::{ColType, ColumnDef, NullableColType, StoredRelationMetadata}; use crate::data::symb::{Symbol, PROG_ENTRY}; use crate::data::value::DataValue; +use crate::fixed_rule::utilities::constant::Constant; +use crate::fixed_rule::{FixedRuleHandle, FixedRuleNotFoundError}; use crate::parse::expr::build_expr; use crate::parse::schema::parse_schema; use crate::parse::{ExtractSpan, Pair, Pairs, Rule, SourceSpan}; use crate::runtime::relation::InputRelationHandle; -use crate::AlgoImpl; +use crate::FixedRule; #[derive(Error, Diagnostic, Debug)] #[error("Query option {0} is not constant")] @@ -94,9 +94,9 @@ fn merge_spans(symbs: &[Symbol]) -> SourceSpan { pub(crate) fn parse_query( src: Pairs<'_>, param_pool: &BTreeMap, - algorithms: &BTreeMap>>, + fixedrithms: &BTreeMap>>, ) -> Result { - let mut progs: BTreeMap = Default::default(); + let mut progs: BTreeMap = Default::default(); let mut out_opts: QueryOutOptions = Default::default(); let mut stored_relation = None; @@ -107,12 +107,12 @@ pub(crate) fn parse_query( match progs.entry(name) { Entry::Vacant(e) => { - e.insert(InputInlineRulesOrAlgo::Rules { rules: vec![rule] }); + e.insert(InputInlineRulesOrFixed::Rules { rules: vec![rule] }); } Entry::Occupied(mut e) => { let key = e.key().to_string(); match e.get_mut() { - InputInlineRulesOrAlgo::Rules { rules: rs } => { + InputInlineRulesOrFixed::Rules { rules: rs } => { #[derive(Debug, Error, Diagnostic)] #[error("Rule {0} has multiple definitions with conflicting heads")] #[diagnostic(code(parser::head_aggr_mismatch))] @@ -134,32 +134,32 @@ pub(crate) fn parse_query( rs.push(rule); } - InputInlineRulesOrAlgo::Algo { algo } => { - let algo_span = algo.span; + InputInlineRulesOrFixed::Fixed { fixed } => { + let fixed_span = fixed.span; bail!(MultipleRuleDefinitionError( e.key().name.to_string(), - vec![rule.span, algo_span] + vec![rule.span, fixed_span] )) } } } } } - Rule::algo_rule => { + Rule::fixed_rule => { let rule_span = pair.extract_span(); - let (name, apply) = parse_algo_rule(pair, param_pool, algorithms)?; + let (name, apply) = parse_fixed_rule(pair, param_pool, fixedrithms)?; match progs.entry(name) { Entry::Vacant(e) => { - e.insert(InputInlineRulesOrAlgo::Algo { algo: apply }); + e.insert(InputInlineRulesOrFixed::Fixed { fixed: apply }); } Entry::Occupied(e) => { let found_name = e.key().name.to_string(); let mut found_span = match e.get() { - InputInlineRulesOrAlgo::Rules { rules } => { + InputInlineRulesOrFixed::Rules { rules } => { rules.iter().map(|r| r.span).collect_vec() } - InputInlineRulesOrAlgo::Algo { algo } => vec![algo.span], + InputInlineRulesOrFixed::Fixed { fixed } => vec![fixed.span], }; found_span.push(rule_span); bail!(MultipleRuleDefinitionError(found_name, found_span)); @@ -173,11 +173,11 @@ pub(crate) fn parse_query( if let Some(found) = progs.get(&name) { let mut found_span = match found { - InputInlineRulesOrAlgo::Rules { rules } => { + InputInlineRulesOrFixed::Rules { rules } => { rules.iter().map(|r| r.span).collect_vec() } - InputInlineRulesOrAlgo::Algo { algo } => { - vec![algo.span] + InputInlineRulesOrFixed::Fixed { fixed } => { + vec![fixed.span] } }; found_span.push(span); @@ -199,12 +199,12 @@ pub(crate) fn parse_query( let data = build_expr(src.next().unwrap(), param_pool)?; let mut options = BTreeMap::new(); options.insert(SmartString::from("data"), data); - let handle = AlgoHandle { + let handle = FixedRuleHandle { name: Symbol::new("Constant", span), }; - let algo_impl = Box::new(Constant); - algo_impl.init_options(&mut options, span)?; - let arity = algo_impl.arity(&options, &head, span)?; + let fixed_impl = Box::new(Constant); + fixed_impl.init_options(&mut options, span)?; + let arity = fixed_impl.arity(&options, &head, span)?; ensure!(arity != 0, EmptyRowForConstRule(span)); ensure!( @@ -213,15 +213,15 @@ pub(crate) fn parse_query( ); progs.insert( name, - InputInlineRulesOrAlgo::Algo { - algo: AlgoApply { - algo: handle, + InputInlineRulesOrFixed::Fixed { + fixed: FixedRuleApply { + fixed_handle: handle, rule_args: vec![], options: Rc::new(options), head, arity, span, - algo_impl: Arc::new(algo_impl), + fixed_impl: Arc::new(fixed_impl), }, }, ); @@ -652,55 +652,55 @@ fn parse_rule_head_arg( }) } -fn parse_algo_rule( +fn parse_fixed_rule( src: Pair<'_>, param_pool: &BTreeMap, - algorithms: &BTreeMap>>, -) -> Result<(Symbol, AlgoApply)> { + fixedrithms: &BTreeMap>>, +) -> Result<(Symbol, FixedRuleApply)> { let mut src = src.into_inner(); let (out_symbol, head, aggr) = parse_rule_head(src.next().unwrap(), param_pool)?; #[derive(Debug, Error, Diagnostic)] - #[error("Algorithm rule cannot be combined with aggregation")] - #[diagnostic(code(parser::algo_aggr_conflict))] - struct AggrInAlgoError(#[label] SourceSpan); + #[error("fixedrithm rule cannot be combined with aggregation")] + #[diagnostic(code(parser::fixed_aggr_conflict))] + struct AggrInfixedError(#[label] SourceSpan); for (a, v) in aggr.iter().zip(head.iter()) { - ensure!(a.is_none(), AggrInAlgoError(v.span)) + ensure!(a.is_none(), AggrInfixedError(v.span)) } let name_pair = src.next().unwrap(); - let algo_name = &name_pair.as_str(); - let mut rule_args: Vec = vec![]; + let fixed_name = &name_pair.as_str(); + let mut rule_args: Vec = vec![]; let mut options: BTreeMap, Expr> = Default::default(); let args_list = src.next().unwrap(); let args_list_span = args_list.extract_span(); for nxt in args_list.into_inner() { match nxt.as_rule() { - Rule::algo_rel => { + Rule::fixed_rel => { let inner = nxt.into_inner().next().unwrap(); let span = inner.extract_span(); match inner.as_rule() { - Rule::algo_rule_rel => { + Rule::fixed_rule_rel => { let mut els = inner.into_inner(); let name = els.next().unwrap(); let bindings = els .map(|v| Symbol::new(v.as_str(), v.extract_span())) .collect_vec(); - rule_args.push(AlgoRuleArg::InMem { + rule_args.push(FixedRuleArg::InMem { name: Symbol::new(name.as_str(), name.extract_span()), bindings, span, }) } - Rule::algo_relation_rel => { + Rule::fixed_relation_rel => { let mut els = inner.into_inner(); let name = els.next().unwrap(); let bindings = els .map(|v| Symbol::new(v.as_str(), v.extract_span())) .collect_vec(); - rule_args.push(AlgoRuleArg::Stored { + rule_args.push(FixedRuleArg::Stored { name: Symbol::new( name.as_str().strip_prefix('*').unwrap(), name.extract_span(), @@ -709,7 +709,7 @@ fn parse_algo_rule( span, }) } - Rule::algo_named_relation_rel => { + Rule::fixed_named_relation_rel => { let mut els = inner.into_inner(); let name = els.next().unwrap(); let bindings = els @@ -725,7 +725,7 @@ fn parse_algo_rule( }) .collect(); - rule_args.push(AlgoRuleArg::NamedStored { + rule_args.push(FixedRuleArg::NamedStored { name: Symbol::new( name.as_str().strip_prefix(':').unwrap(), name.extract_span(), @@ -737,7 +737,7 @@ fn parse_algo_rule( _ => unreachable!(), } } - Rule::algo_opt_pair => { + Rule::fixed_opt_pair => { let mut inner = nxt.into_inner(); let name = inner.next().unwrap().as_str(); let val = inner.next().unwrap(); @@ -748,12 +748,13 @@ fn parse_algo_rule( } } - let algo = AlgoHandle::new(algo_name, name_pair.extract_span()); + let fixed = FixedRuleHandle::new(fixed_name, name_pair.extract_span()); - let algo_impl = algorithms.get(&algo.name as &str) - .ok_or_else(|| AlgoNotFoundError(algo.name.to_string(), name_pair.extract_span()))?; - algo_impl.init_options(&mut options, args_list_span)?; - let arity = algo_impl.arity(&options, &head, name_pair.extract_span())?; + let fixed_impl = fixedrithms + .get(&fixed.name as &str) + .ok_or_else(|| FixedRuleNotFoundError(fixed.name.to_string(), name_pair.extract_span()))?; + fixed_impl.init_options(&mut options, args_list_span)?; + let arity = fixed_impl.arity(&options, &head, name_pair.extract_span())?; ensure!( head.is_empty() || arity == head.len(), @@ -762,14 +763,14 @@ fn parse_algo_rule( Ok(( out_symbol, - AlgoApply { - algo, + FixedRuleApply { + fixed_handle: fixed, rule_args, options: Rc::new(options), head, arity, span: args_list_span, - algo_impl: algo_impl.clone(), + fixed_impl: fixed_impl.clone(), }, )) } @@ -797,9 +798,9 @@ fn make_empty_const_rule(prog: &mut InputProgram, bindings: &[Symbol]) { ); prog.prog.insert( entry_symbol, - InputInlineRulesOrAlgo::Algo { - algo: AlgoApply { - algo: AlgoHandle { + InputInlineRulesOrFixed::Fixed { + fixed: FixedRuleApply { + fixed_handle: FixedRuleHandle { name: Symbol::new("Constant", Default::default()), }, rule_args: vec![], @@ -807,7 +808,7 @@ fn make_empty_const_rule(prog: &mut InputProgram, bindings: &[Symbol]) { head: bindings.to_vec(), arity: bindings.len(), span: Default::default(), - algo_impl: Arc::new(Box::new(Constant)), + fixed_impl: Arc::new(Box::new(Constant)), }, }, ); diff --git a/cozo-core/src/parse/sys.rs b/cozo-core/src/parse/sys.rs index 0f91890e..bd46570e 100644 --- a/cozo-core/src/parse/sys.rs +++ b/cozo-core/src/parse/sys.rs @@ -19,7 +19,7 @@ use crate::data::value::DataValue; use crate::parse::query::parse_query; use crate::parse::{ExtractSpan, Pairs, Rule, SourceSpan}; use crate::runtime::relation::AccessLevel; -use crate::AlgoImpl; +use crate::FixedRule; pub(crate) enum SysOp { Compact, @@ -43,7 +43,7 @@ struct ProcessIdError(String, #[label] SourceSpan); pub(crate) fn parse_sys( mut src: Pairs<'_>, param_pool: &BTreeMap, - algorithms: &BTreeMap>>, + algorithms: &BTreeMap>>, ) -> Result { let inner = src.next().unwrap(); Ok(match inner.as_rule() { diff --git a/cozo-core/src/query/compile.rs b/cozo-core/src/query/compile.rs index 0ce314a5..9f5515cb 100644 --- a/cozo-core/src/query/compile.rs +++ b/cozo-core/src/query/compile.rs @@ -15,7 +15,7 @@ use thiserror::Error; use crate::data::aggr::Aggregation; use crate::data::expr::Expr; use crate::data::program::{ - MagicAlgoApply, MagicAtom, MagicInlineRule, MagicRulesOrAlgo, MagicSymbol, + MagicFixedRuleApply, MagicAtom, MagicInlineRule, MagicRulesOrFixed, MagicSymbol, StratifiedMagicProgram, }; use crate::data::symb::Symbol; @@ -30,7 +30,7 @@ pub(crate) type CompiledProgram = BTreeMap; #[derive(Debug)] pub(crate) enum CompiledRuleSet { Rules(Vec), - Algo(MagicAlgoApply), + Fixed(MagicFixedRuleApply), } #[derive(Debug, Copy, Clone, Eq, PartialEq)] @@ -44,7 +44,7 @@ impl CompiledRuleSet { pub(crate) fn arity(&self) -> usize { match self { CompiledRuleSet::Rules(rs) => rs[0].aggr.len(), - CompiledRuleSet::Algo(algo) => algo.arity, + CompiledRuleSet::Fixed(fixed) => fixed.arity, } } pub(crate) fn aggr_kind(&self) -> AggrKind { @@ -72,7 +72,7 @@ impl CompiledRuleSet { (true, false) => AggrKind::Meet, } } - CompiledRuleSet::Algo(_) => AggrKind::None, + CompiledRuleSet::Fixed(_) => AggrKind::None, } } } @@ -118,7 +118,7 @@ impl<'a> SessionTx<'a> { .into_iter() .map(|(k, body)| -> Result<(MagicSymbol, CompiledRuleSet)> { match body { - MagicRulesOrAlgo::Rules { rules: body } => { + MagicRulesOrFixed::Rules { rules: body } => { let mut collected = Vec::with_capacity(body.len()); for rule in body.iter() { let header = &rule.head; @@ -139,8 +139,8 @@ impl<'a> SessionTx<'a> { Ok((k, CompiledRuleSet::Rules(collected))) } - MagicRulesOrAlgo::Algo { algo: algo_apply } => { - Ok((k, CompiledRuleSet::Algo(algo_apply))) + MagicRulesOrFixed::Fixed { fixed } => { + Ok((k, CompiledRuleSet::Fixed(fixed))) } } }) diff --git a/cozo-core/src/query/eval.rs b/cozo-core/src/query/eval.rs index 95fd601d..5980cee0 100644 --- a/cozo-core/src/query/eval.rs +++ b/cozo-core/src/query/eval.rs @@ -13,7 +13,7 @@ use itertools::Itertools; use log::{debug, trace}; use miette::Result; -use crate::algo::AlgoPayload; +use crate::fixed_rule::FixedRulePayload; use crate::data::aggr::Aggregation; use crate::data::program::{MagicSymbol, NoEntryError}; use crate::data::symb::{Symbol, PROG_ENTRY}; @@ -152,15 +152,15 @@ impl<'a> SessionTx<'a> { new.wrap() } }, - CompiledRuleSet::Algo(algo_apply) => { - let algo_impl = algo_apply.algo_impl.as_ref(); + CompiledRuleSet::Fixed(fixed) => { + let fixed_impl = fixed.fixed_impl.as_ref(); let mut out = RegularTempStore::default(); - let payload = AlgoPayload { - manifest: algo_apply, + let payload = FixedRulePayload { + manifest: fixed, stores, tx: self, }; - algo_impl.run(payload, &mut out, poison.clone())?; + fixed_impl.run(payload, &mut out, poison.clone())?; out.wrap() } }; @@ -199,7 +199,7 @@ impl<'a> SessionTx<'a> { } } - CompiledRuleSet::Algo(_) => { + CompiledRuleSet::Fixed(_) => { // no need to do anything, algos are only calculated once RegularTempStore::default().wrap() } diff --git a/cozo-core/src/query/graph.rs b/cozo-core/src/query/graph.rs index 5f71c4f2..b131e537 100644 --- a/cozo-core/src/query/graph.rs +++ b/cozo-core/src/query/graph.rs @@ -12,7 +12,7 @@ use std::fmt::Debug; use miette::Result; use itertools::Itertools; -use crate::algo::strongly_connected_components::TarjanScc; +use crate::fixed_rule::algos::strongly_connected_components::TarjanScc; use crate::runtime::db::Poison; pub(crate) type Graph = BTreeMap>; diff --git a/cozo-core/src/query/magic.rs b/cozo-core/src/query/magic.rs index bb1ed594..d8b24f65 100644 --- a/cozo-core/src/query/magic.rs +++ b/cozo-core/src/query/magic.rs @@ -15,9 +15,9 @@ use smallvec::SmallVec; use smartstring::SmartString; use crate::data::program::{ - AlgoRuleArg, MagicAlgoApply, MagicAlgoRuleArg, MagicAtom, MagicInlineRule, MagicProgram, - MagicRelationApplyAtom, MagicRuleApplyAtom, MagicRulesOrAlgo, MagicSymbol, - NormalFormAlgoOrRules, NormalFormAtom, NormalFormInlineRule, NormalFormProgram, + FixedRuleArg, MagicFixedRuleApply, MagicFixedRuleRuleArg, MagicAtom, MagicInlineRule, MagicProgram, + MagicRelationApplyAtom, MagicRuleApplyAtom, MagicRulesOrFixed, MagicSymbol, + NormalFormRulesOrFixed, NormalFormAtom, NormalFormInlineRule, NormalFormProgram, StratifiedMagicProgram, StratifiedNormalFormProgram, }; use crate::data::symb::{Symbol, PROG_ENTRY}; @@ -29,7 +29,7 @@ impl NormalFormProgram { pub(crate) fn exempt_aggr_rules_for_magic_sets(&self, exempt_rules: &mut BTreeSet) { for (name, rule_set) in self.prog.iter() { match rule_set { - NormalFormAlgoOrRules::Rules { rules: rule_set } => { + NormalFormRulesOrFixed::Rules { rules: rule_set } => { 'outer: for rule in rule_set.iter() { for aggr in rule.aggr.iter() { if aggr.is_some() { @@ -39,7 +39,7 @@ impl NormalFormProgram { } } } - NormalFormAlgoOrRules::Algo { algo: _ } => {} + NormalFormRulesOrFixed::Fixed { fixed: _ } => {} } } } @@ -67,13 +67,13 @@ impl MagicProgram { }; for (rule_head, ruleset) in self.prog { match ruleset { - MagicRulesOrAlgo::Rules { rules: ruleset } => { + MagicRulesOrFixed::Rules { rules: ruleset } => { magic_rewrite_ruleset(rule_head, ruleset, &mut ret_prog); } - MagicRulesOrAlgo::Algo { algo: algo_apply } => { + MagicRulesOrFixed::Fixed { fixed } => { ret_prog .prog - .insert(rule_head, MagicRulesOrAlgo::Algo { algo: algo_apply }); + .insert(rule_head, MagicRulesOrFixed::Fixed { fixed }); } } } @@ -138,7 +138,7 @@ fn magic_rewrite_ruleset( ret_prog.prog.insert( sup_kw.clone(), - MagicRulesOrAlgo::Rules { + MagicRulesOrFixed::Rules { rules: vec![MagicInlineRule { head: sup_args.clone(), aggr: sup_aggr, @@ -257,7 +257,7 @@ impl NormalFormProgram { let mut downstream_rules: BTreeSet = Default::default(); for rules in self.prog.values() { match rules { - NormalFormAlgoOrRules::Rules { rules } => { + NormalFormRulesOrFixed::Rules { rules } => { for rule in rules { for atom in rule.body.iter() { match atom { @@ -272,9 +272,9 @@ impl NormalFormProgram { } } } - NormalFormAlgoOrRules::Algo { algo } => { - for rel in algo.rule_args.iter() { - if let AlgoRuleArg::InMem { name, .. } = rel { + NormalFormRulesOrFixed::Fixed { fixed } => { + for rel in fixed.rule_args.iter() { + if let FixedRuleArg::InMem { name, .. } = rel { downstream_rules.insert(name.clone()); } } @@ -302,42 +302,42 @@ impl NormalFormProgram { continue; } match rules { - NormalFormAlgoOrRules::Algo { algo: algo_apply } => { + NormalFormRulesOrFixed::Fixed { fixed } => { adorned_prog.prog.insert( MagicSymbol::Muggle { inner: rule_name.clone(), }, - MagicRulesOrAlgo::Algo { - algo: MagicAlgoApply { - span: algo_apply.span, - algo: algo_apply.algo.clone(), - algo_impl: algo_apply.algo_impl.clone(), - rule_args: algo_apply + MagicRulesOrFixed::Fixed { + fixed: MagicFixedRuleApply { + span: fixed.span, + fixed_handle: fixed.fixed_handle.clone(), + fixed_impl: fixed.fixed_impl.clone(), + rule_args: fixed .rule_args .iter() - .map(|r| -> Result { + .map(|r| -> Result { Ok(match r { - AlgoRuleArg::InMem { + FixedRuleArg::InMem { name, bindings, span, - } => MagicAlgoRuleArg::InMem { + } => MagicFixedRuleRuleArg::InMem { name: MagicSymbol::Muggle { inner: name.clone(), }, bindings: bindings.clone(), span: *span, }, - AlgoRuleArg::Stored { + FixedRuleArg::Stored { name, bindings, span, - } => MagicAlgoRuleArg::Stored { + } => MagicFixedRuleRuleArg::Stored { name: name.clone(), bindings: bindings.clone(), span: *span, }, - AlgoRuleArg::NamedStored { + FixedRuleArg::NamedStored { name, bindings, span, @@ -374,7 +374,7 @@ impl NormalFormProgram { Some(k) => k.clone(), }) .collect_vec(); - MagicAlgoRuleArg::Stored { + MagicFixedRuleRuleArg::Stored { name: name.clone(), bindings: new_bindings, span: *span, @@ -383,13 +383,13 @@ impl NormalFormProgram { }) }) .try_collect()?, - options: algo_apply.options.clone(), - arity: algo_apply.arity, + options: fixed.options.clone(), + arity: fixed.arity, }, }, ); } - NormalFormAlgoOrRules::Rules { rules } => { + NormalFormRulesOrFixed::Rules { rules } => { let mut adorned_rules = Vec::with_capacity(rules.len()); for rule in rules { let adorned_rule = rule.adorn( @@ -403,7 +403,7 @@ impl NormalFormProgram { MagicSymbol::Muggle { inner: rule_name.clone(), }, - MagicRulesOrAlgo::Rules { + MagicRulesOrFixed::Rules { rules: adorned_rules, }, ); @@ -436,7 +436,7 @@ impl NormalFormProgram { } adorned_prog.prog.insert( head, - MagicRulesOrAlgo::Rules { + MagicRulesOrFixed::Rules { rules: adorned_rules, }, ); diff --git a/cozo-core/src/query/stored.rs b/cozo-core/src/query/stored.rs index e1ff40c2..84f930be 100644 --- a/cozo-core/src/query/stored.rs +++ b/cozo-core/src/query/stored.rs @@ -15,14 +15,14 @@ use miette::{bail, Diagnostic, Result, WrapErr}; use smartstring::SmartString; use thiserror::Error; -use crate::algo::constant::Constant; -use crate::algo::AlgoHandle; +use crate::fixed_rule::FixedRuleHandle; use crate::data::expr::Expr; -use crate::data::program::{AlgoApply, InputInlineRulesOrAlgo, InputProgram, RelationOp}; +use crate::data::program::{FixedRuleApply, InputInlineRulesOrFixed, InputProgram, RelationOp}; use crate::data::relation::{ColumnDef, NullableColType}; use crate::data::symb::Symbol; use crate::data::tuple::{Tuple, ENCODED_KEY_MIN_LEN}; use crate::data::value::DataValue; +use crate::fixed_rule::utilities::constant::Constant; use crate::parse::parse_script; use crate::runtime::relation::{AccessLevel, InputRelationHandle, InsufficientAccessLevel}; use crate::runtime::transact::SessionTx; @@ -43,8 +43,6 @@ impl<'a> SessionTx<'a> { meta: &InputRelationHandle, headers: &[Symbol], ) -> Result, Vec)>> { - // TODO - let algorithms = BTreeMap::new(); let mut to_clear = vec![]; let mut replaced_old_triggers = None; if op == RelationOp::Replace { @@ -60,7 +58,7 @@ impl<'a> SessionTx<'a> { replaced_old_triggers = Some((old_handle.put_triggers, old_handle.rm_triggers)) } for trigger in &old_handle.replace_triggers { - let program = parse_script(trigger, &Default::default(), &algorithms)? + let program = parse_script(trigger, &Default::default(), &db.algorithms)? .get_single_program()?; let (_, cleanups) = db.run_query(self, program).map_err(|err| { @@ -437,9 +435,9 @@ fn make_const_rule( let bindings_arity = bindings.len(); program.prog.insert( rule_symbol, - InputInlineRulesOrAlgo::Algo { - algo: AlgoApply { - algo: AlgoHandle { + InputInlineRulesOrFixed::Fixed { + fixed: FixedRuleApply { + fixed_handle: FixedRuleHandle { name: Symbol::new("Constant", Default::default()), }, rule_args: vec![], @@ -447,7 +445,7 @@ fn make_const_rule( head: bindings, arity: bindings_arity, span: Default::default(), - algo_impl: Arc::new(Box::new(Constant)), + fixed_impl: Arc::new(Box::new(Constant)), }, }, ); diff --git a/cozo-core/src/query/stratify.rs b/cozo-core/src/query/stratify.rs index a8e098f4..82d96281 100644 --- a/cozo-core/src/query/stratify.rs +++ b/cozo-core/src/query/stratify.rs @@ -14,7 +14,7 @@ use miette::{ensure, Diagnostic, Result}; use thiserror::Error; use crate::data::program::{ - AlgoRuleArg, MagicSymbol, NormalFormAlgoOrRules, NormalFormAtom, NormalFormProgram, + FixedRuleArg, MagicSymbol, NormalFormRulesOrFixed, NormalFormAtom, NormalFormProgram, StratifiedNormalFormProgram, }; use crate::data::symb::{Symbol, PROG_ENTRY}; @@ -43,7 +43,7 @@ fn convert_normal_form_program_to_graph( .prog .iter() .filter_map(|(k, ruleset)| match ruleset { - NormalFormAlgoOrRules::Rules { rules: ruleset } => { + NormalFormRulesOrFixed::Rules { rules: ruleset } => { let has_aggr = ruleset .iter() .any(|rule| rule.aggr.iter().any(|a| a.is_some())); @@ -60,22 +60,22 @@ fn convert_normal_form_program_to_graph( None } } - NormalFormAlgoOrRules::Algo { algo: _ } => None, + NormalFormRulesOrFixed::Fixed { fixed: _ } => None, }) .collect(); - let algo_rules: BTreeSet<_> = nf_prog + let fixed_rules: BTreeSet<_> = nf_prog .prog .iter() .filter_map(|(k, ruleset)| match ruleset { - NormalFormAlgoOrRules::Rules { rules: _ } => None, - NormalFormAlgoOrRules::Algo { algo: _ } => Some(k), + NormalFormRulesOrFixed::Rules { rules: _ } => None, + NormalFormRulesOrFixed::Fixed { fixed: _ } => Some(k), }) .collect(); nf_prog .prog .iter() .map(|(k, ruleset)| match ruleset { - NormalFormAlgoOrRules::Rules { rules: ruleset } => { + NormalFormRulesOrFixed::Rules { rules: ruleset } => { let mut ret: BTreeMap<&Symbol, bool> = BTreeMap::default(); let has_aggr = ruleset .iter() @@ -93,18 +93,18 @@ fn convert_normal_form_program_to_graph( for (found_key, is_negated) in contained { let found_key_is_meet = meet_rules.contains(found_key) && found_key != k; - let found_key_is_algo = algo_rules.contains(found_key); + let found_key_is_fixed_rule = fixed_rules.contains(found_key); match ret.entry(found_key) { Entry::Vacant(e) => { if has_aggr { if is_meet && k == found_key { - e.insert(found_key_is_algo || is_negated); + e.insert(found_key_is_fixed_rule || is_negated); } else { e.insert(true); } } else { e.insert( - found_key_is_algo || found_key_is_meet || is_negated, + found_key_is_fixed_rule || found_key_is_meet || is_negated, ); } } @@ -112,12 +112,12 @@ fn convert_normal_form_program_to_graph( let old = *e.get(); let new_val = if has_aggr { if is_meet && k == found_key { - found_key_is_algo || found_key_is_meet || is_negated + found_key_is_fixed_rule || found_key_is_meet || is_negated } else { true } } else { - found_key_is_algo || found_key_is_meet || is_negated + found_key_is_fixed_rule || found_key_is_meet || is_negated }; e.insert(old || new_val); } @@ -127,14 +127,14 @@ fn convert_normal_form_program_to_graph( } (k, ret) } - NormalFormAlgoOrRules::Algo { algo } => { + NormalFormRulesOrFixed::Fixed { fixed } => { let mut ret: BTreeMap<&Symbol, bool> = BTreeMap::default(); - for rel in &algo.rule_args { + for rel in &fixed.rule_args { match rel { - AlgoRuleArg::InMem { name, .. } => { + FixedRuleArg::InMem { name, .. } => { ret.insert(name, true); } - AlgoRuleArg::Stored { .. } | AlgoRuleArg::NamedStored { .. } => {} + FixedRuleArg::Stored { .. } | FixedRuleArg::NamedStored { .. } => {} } } (k, ret) diff --git a/cozo-core/src/runtime/db.rs b/cozo-core/src/runtime/db.rs index 6d7743f7..97202e4e 100644 --- a/cozo-core/src/runtime/db.rs +++ b/cozo-core/src/runtime/db.rs @@ -38,8 +38,8 @@ use crate::query::ra::{ use crate::runtime::relation::{AccessLevel, InsufficientAccessLevel, RelationHandle, RelationId}; use crate::runtime::transact::SessionTx; use crate::storage::{Storage, StoreTx}; -use crate::{decode_tuple_from_kv, AlgoImpl}; -use crate::algo::DEFAULT_ALGOS; +use crate::{decode_tuple_from_kv, FixedRule}; +use crate::fixed_rule::DEFAULT_FIXED_RULES; struct RunningQueryHandle { started_at: f64, @@ -72,7 +72,7 @@ pub struct Db { relation_store_id: Arc, queries_count: Arc, running_queries: Arc>>, - pub(crate) algorithms: Arc>>>, + pub(crate) algorithms: Arc>>>, } impl Debug for Db { @@ -118,7 +118,7 @@ impl<'s, S: Storage<'s>> Db { relation_store_id: Arc::new(Default::default()), queries_count: Arc::new(Default::default()), running_queries: Arc::new(Mutex::new(Default::default())), - algorithms: DEFAULT_ALGOS.clone(), + algorithms: DEFAULT_FIXED_RULES.clone(), }; Ok(ret) } @@ -626,7 +626,7 @@ impl<'s, S: Storage<'s>> Db { ret.extend(ret_for_relation) } } - CompiledRuleSet::Algo(_) => ret.push(json!({ + CompiledRuleSet::Fixed(_) => ret.push(json!({ STRATUM: stratum, ATOM_IDX: 0, OP: "algo",