naming consistency

main
Ziyang Hu 2 years ago
parent 9cadfc48a7
commit 82dd566717

@ -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 ~ "]"}

@ -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<InputInlineRule> },
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<AlgoRuleArg>,
pub(crate) struct FixedRuleApply {
pub(crate) fixed_handle: FixedRuleHandle,
pub(crate) rule_args: Vec<FixedRuleArg>,
pub(crate) options: Rc<BTreeMap<SmartString<LazyCompact>, Expr>>,
pub(crate) head: Vec<Symbol>,
pub(crate) arity: usize,
pub(crate) span: SourceSpan,
pub(crate) algo_impl: Arc<Box<dyn AlgoImpl>>,
pub(crate) fixed_impl: Arc<Box<dyn FixedRule>>,
}
impl AlgoApply {
impl FixedRuleApply {
pub(crate) fn arity(&self) -> Result<usize> {
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<MagicAlgoRuleArg>,
pub(crate) struct MagicFixedRuleApply {
pub(crate) fixed_handle: FixedRuleHandle,
pub(crate) rule_args: Vec<MagicFixedRuleRuleArg>,
pub(crate) options: Rc<BTreeMap<SmartString<LazyCompact>, Expr>>,
pub(crate) span: SourceSpan,
pub(crate) arity: usize,
pub(crate) algo_impl: Arc<Box<dyn AlgoImpl>>,
pub(crate) fixed_impl: Arc<Box<dyn FixedRule>>,
}
#[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<MagicSymbol, EpochStore>,
) -> 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<Symbol>,
@ -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<Symbol>,
@ -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<Symbol, usize> {
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<Symbol, InputInlineRulesOrAlgo>,
pub(crate) prog: BTreeMap<Symbol, InputInlineRulesOrFixed>,
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<usize> {
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<Vec<Symbol>> {
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<Symbol, _> = 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<NormalFormProgram>);
#[derive(Debug)]
pub(crate) enum NormalFormAlgoOrRules {
pub(crate) enum NormalFormRulesOrFixed {
Rules { rules: Vec<NormalFormInlineRule> },
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<Symbol, NormalFormAlgoOrRules>,
pub(crate) prog: BTreeMap<Symbol, NormalFormRulesOrFixed>,
}
#[derive(Debug)]
pub(crate) struct StratifiedMagicProgram(pub(crate) Vec<MagicProgram>);
#[derive(Debug)]
pub(crate) enum MagicRulesOrAlgo {
pub(crate) enum MagicRulesOrFixed {
Rules { rules: Vec<MagicInlineRule> },
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<usize> {
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<MagicInlineRule>> {
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<MagicSymbol, MagicRulesOrAlgo>,
pub(crate) prog: BTreeMap<MagicSymbol, MagicRulesOrFixed>,
}
#[derive(Clone, Ord, PartialOrd, Eq, PartialEq)]

@ -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<()> {

@ -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<DataValue>)> {

@ -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<()> {

@ -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<()> {

@ -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<()> {

@ -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<()> {

@ -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<()> {

@ -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]

@ -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;

@ -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<()> {

@ -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<()> {

@ -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<()> {

@ -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<()> {

@ -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<()> {

@ -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<()> {

@ -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<()> {

@ -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<MagicSymbol, EpochStore>,
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<MagicSymbol, EpochStore>,
tx: &'a SessionTx<'b>,
}
impl<'a, 'b> AlgoInputRelation<'a, 'b> {
impl<'a, 'b> FixedRuleInputRelation<'a, 'b> {
pub fn arity(&self) -> Result<usize> {
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<TupleIter<'a>> {
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<TupleIter<'_>> {
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<usize>>, Vec<DataValue>, BTreeMap<DataValue, usize>)> {
self.arg_manifest
.convert_edge_to_graph(undirected, self.tx, self.stores)
let mut graph: Vec<Vec<usize>> = vec![];
let mut indices: Vec<DataValue> = vec![];
let mut inv_indices: BTreeMap<DataValue, usize> = 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<DataValue, usize>,
bool,
)> {
self.arg_manifest.convert_edge_to_weighted_graph(
undirected,
allow_negative_edges,
self.tx,
self.stores,
)
let mut graph: Vec<Vec<(usize, f64)>> = vec![];
let mut indices: Vec<DataValue> = vec![];
let mut inv_indices: BTreeMap<DataValue, usize> = 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<AlgoInputRelation<'a, 'b>> {
impl<'a, 'b> FixedRulePayload<'a, 'b> {
pub fn get_input(&self, idx: usize) -> Result<FixedRuleInputRelation<'a, 'b>> {
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<BTreeMap<String, Arc<Box<dyn AlgoImpl>>>> = {
pub(crate) static ref DEFAULT_FIXED_RULES: Arc<BTreeMap<String, Arc<Box<dyn FixedRule>>>> = {
Arc::new(BTreeMap::from([
#[cfg(feature = "graph-algo")]
(
"ClusteringCoefficients".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(ClusteringCoefficients)),
Arc::<Box<dyn FixedRule>>::new(Box::new(ClusteringCoefficients)),
),
#[cfg(feature = "graph-algo")]
(
"DegreeCentrality".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(DegreeCentrality)),
Arc::<Box<dyn FixedRule>>::new(Box::new(DegreeCentrality)),
),
#[cfg(feature = "graph-algo")]
(
"ClosenessCentrality".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(ClosenessCentrality)),
Arc::<Box<dyn FixedRule>>::new(Box::new(ClosenessCentrality)),
),
#[cfg(feature = "graph-algo")]
(
"BetweennessCentrality".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(BetweennessCentrality)),
Arc::<Box<dyn FixedRule>>::new(Box::new(BetweennessCentrality)),
),
#[cfg(feature = "graph-algo")]
(
"DepthFirstSearch".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(Dfs)),
Arc::<Box<dyn FixedRule>>::new(Box::new(Dfs)),
),
#[cfg(feature = "graph-algo")]
(
"DFS".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(Dfs)),
Arc::<Box<dyn FixedRule>>::new(Box::new(Dfs)),
),
#[cfg(feature = "graph-algo")]
(
"BreadthFirstSearch".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(Bfs)),
Arc::<Box<dyn FixedRule>>::new(Box::new(Bfs)),
),
#[cfg(feature = "graph-algo")]
(
"BFS".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(Bfs)),
Arc::<Box<dyn FixedRule>>::new(Box::new(Bfs)),
),
#[cfg(feature = "graph-algo")]
(
"ShortestPathDijkstra".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(ShortestPathDijkstra)),
Arc::<Box<dyn FixedRule>>::new(Box::new(ShortestPathDijkstra)),
),
#[cfg(feature = "graph-algo")]
(
"ShortestPathAStar".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(ShortestPathAStar)),
Arc::<Box<dyn FixedRule>>::new(Box::new(ShortestPathAStar)),
),
#[cfg(feature = "graph-algo")]
(
"KShortestPathYen".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(KShortestPathYen)),
Arc::<Box<dyn FixedRule>>::new(Box::new(KShortestPathYen)),
),
#[cfg(feature = "graph-algo")]
(
"MinimumSpanningTreePrim".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(MinimumSpanningTreePrim)),
Arc::<Box<dyn FixedRule>>::new(Box::new(MinimumSpanningTreePrim)),
),
#[cfg(feature = "graph-algo")]
(
"MinimumSpanningForestKruskal".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(MinimumSpanningForestKruskal)),
Arc::<Box<dyn FixedRule>>::new(Box::new(MinimumSpanningForestKruskal)),
),
#[cfg(feature = "graph-algo")]
(
"TopSort".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(TopSort)),
Arc::<Box<dyn FixedRule>>::new(Box::new(TopSort)),
),
#[cfg(feature = "graph-algo")]
(
"ConnectedComponents".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(StronglyConnectedComponent::new(false))),
Arc::<Box<dyn FixedRule>>::new(Box::new(StronglyConnectedComponent::new(false))),
),
#[cfg(feature = "graph-algo")]
(
"StronglyConnectedComponents".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(StronglyConnectedComponent::new(true))),
Arc::<Box<dyn FixedRule>>::new(Box::new(StronglyConnectedComponent::new(true))),
),
#[cfg(feature = "graph-algo")]
(
"SCC".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(StronglyConnectedComponent::new(true))),
Arc::<Box<dyn FixedRule>>::new(Box::new(StronglyConnectedComponent::new(true))),
),
#[cfg(feature = "graph-algo")]
(
"PageRank".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(PageRank)),
Arc::<Box<dyn FixedRule>>::new(Box::new(PageRank)),
),
#[cfg(feature = "graph-algo")]
(
"CommunityDetectionLouvain".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(CommunityDetectionLouvain)),
Arc::<Box<dyn FixedRule>>::new(Box::new(CommunityDetectionLouvain)),
),
#[cfg(feature = "graph-algo")]
(
"LabelPropagation".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(LabelPropagation)),
Arc::<Box<dyn FixedRule>>::new(Box::new(LabelPropagation)),
),
#[cfg(feature = "graph-algo")]
(
"RandomWalk".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(RandomWalk)),
Arc::<Box<dyn FixedRule>>::new(Box::new(RandomWalk)),
),
(
"ReorderSort".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(ReorderSort)),
Arc::<Box<dyn FixedRule>>::new(Box::new(ReorderSort)),
),
(
"JsonReader".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(JsonReader)),
Arc::<Box<dyn FixedRule>>::new(Box::new(JsonReader)),
),
(
"CsvReader".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(CsvReader)),
Arc::<Box<dyn FixedRule>>::new(Box::new(CsvReader)),
),
(
"Constant".to_string(),
Arc::<Box<dyn AlgoImpl>>::new(Box::new(Constant)),
Arc::<Box<dyn FixedRule>>::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<MagicSymbol, EpochStore>,
) -> Result<(
Vec<Vec<(usize, f64)>>,
Vec<DataValue>,
BTreeMap<DataValue, usize>,
bool,
)> {
let mut graph: Vec<Vec<(usize, f64)>> = vec![];
let mut indices: Vec<DataValue> = vec![];
let mut inv_indices: BTreeMap<DataValue, usize> = 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<MagicSymbol, EpochStore>,
) -> Result<(Vec<Vec<usize>>, Vec<DataValue>, BTreeMap<DataValue, usize>)> {
let mut graph: Vec<Vec<usize>> = vec![];
let mut indices: Vec<DataValue> = vec![];
let mut inv_indices: BTreeMap<DataValue, usize> = 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<MagicSymbol, EpochStore>,
) -> Result<TupleIter<'a>> {
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<MagicSymbol, EpochStore>,
) -> Result<usize> {
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<MagicSymbol, EpochStore>,
) -> Result<TupleIter<'a>> {
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))
}
})
}
}

@ -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<SmartString<LazyCompact>, 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(),
}),
};

@ -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() {

@ -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<()> {

@ -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;

@ -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<()> {

@ -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()
})
}

@ -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

@ -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<NullableColType> {
pub(crate) fn parse_script(
src: &str,
param_pool: &BTreeMap<String, DataValue>,
algorithms: &BTreeMap<String, Arc<Box<dyn AlgoImpl>>>,
algorithms: &BTreeMap<String, Arc<Box<dyn FixedRule>>>,
) -> Result<CozoScript> {
let parsed = CozoScriptParser::parse(Rule::script, src)
.map_err(|err| {

@ -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<String, DataValue>,
algorithms: &BTreeMap<String, Arc<Box<dyn AlgoImpl>>>,
fixedrithms: &BTreeMap<String, Arc<Box<dyn FixedRule>>>,
) -> Result<InputProgram> {
let mut progs: BTreeMap<Symbol, InputInlineRulesOrAlgo> = Default::default();
let mut progs: BTreeMap<Symbol, InputInlineRulesOrFixed> = 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<String, DataValue>,
algorithms: &BTreeMap<String, Arc<Box<dyn AlgoImpl>>>,
) -> Result<(Symbol, AlgoApply)> {
fixedrithms: &BTreeMap<String, Arc<Box<dyn FixedRule>>>,
) -> 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<AlgoRuleArg> = vec![];
let fixed_name = &name_pair.as_str();
let mut rule_args: Vec<FixedRuleArg> = vec![];
let mut options: BTreeMap<SmartString<LazyCompact>, 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)),
},
},
);

@ -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<String, DataValue>,
algorithms: &BTreeMap<String, Arc<Box<dyn AlgoImpl>>>,
algorithms: &BTreeMap<String, Arc<Box<dyn FixedRule>>>,
) -> Result<SysOp> {
let inner = src.next().unwrap();
Ok(match inner.as_rule() {

@ -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<MagicSymbol, CompiledRuleSet>;
#[derive(Debug)]
pub(crate) enum CompiledRuleSet {
Rules(Vec<CompiledRule>),
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)))
}
}
})

@ -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()
}

@ -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<T> = BTreeMap<T, Vec<T>>;

@ -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<Symbol>) {
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<Symbol> = 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<MagicAlgoRuleArg> {
.map(|r| -> Result<MagicFixedRuleRuleArg> {
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,
},
);

@ -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<(Vec<u8>, Vec<u8>)>> {
// 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)),
},
},
);

@ -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)

@ -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<S> {
relation_store_id: Arc<AtomicU64>,
queries_count: Arc<AtomicU64>,
running_queries: Arc<Mutex<BTreeMap<u64, RunningQueryHandle>>>,
pub(crate) algorithms: Arc<BTreeMap<String, Arc<Box<dyn AlgoImpl>>>>,
pub(crate) algorithms: Arc<BTreeMap<String, Arc<Box<dyn FixedRule>>>>,
}
impl<S> Debug for Db<S> {
@ -118,7 +118,7 @@ impl<'s, S: Storage<'s>> Db<S> {
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<S> {
ret.extend(ret_for_relation)
}
}
CompiledRuleSet::Algo(_) => ret.push(json!({
CompiledRuleSet::Fixed(_) => ret.push(json!({
STRATUM: stratum,
ATOM_IDX: 0,
OP: "algo",

Loading…
Cancel
Save