use std::collections::HashMap;
use std::fmt;
#[derive(Debug, Clone, PartialEq)]
pub struct N3Rule {
pub antecedent: Vec<N3Formula>,
pub consequent: Vec<N3Formula>,
pub universals: Vec<String>,
pub existentials: Vec<String>,
}
impl N3Rule {
pub fn new(antecedent: Vec<N3Formula>, consequent: Vec<N3Formula>) -> Self {
Self {
antecedent,
consequent,
universals: Vec::new(),
existentials: Vec::new(),
}
}
pub fn with_universals(mut self, vars: Vec<String>) -> Self {
self.universals = vars;
self
}
pub fn with_existentials(mut self, vars: Vec<String>) -> Self {
self.existentials = vars;
self
}
}
impl fmt::Display for N3Rule {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"N3Rule({} antecedent(s) => {} consequent(s))",
self.antecedent.len(),
self.consequent.len()
)
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum N3Formula {
Triple {
subject: N3Term,
predicate: N3Term,
object: N3Term,
},
Graph(Vec<N3Formula>),
BuiltIn(N3BuiltIn),
}
#[derive(Debug, Clone, PartialEq)]
pub enum N3Term {
Iri(String),
Literal {
value: String,
datatype: Option<String>,
lang: Option<String>,
},
BlankNode(String),
Variable(String),
Universal(String),
NestedFormula(Box<Vec<N3Formula>>),
}
impl N3Term {
pub fn value_str(&self) -> Option<&str> {
match self {
N3Term::Iri(s) | N3Term::BlankNode(s) | N3Term::Variable(s) | N3Term::Universal(s) => {
Some(s.as_str())
}
N3Term::Literal { value, .. } => Some(value.as_str()),
N3Term::NestedFormula(_) => None,
}
}
pub fn is_variable(&self) -> bool {
matches!(self, N3Term::Variable(_) | N3Term::Universal(_))
}
}
impl fmt::Display for N3Term {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
N3Term::Iri(s) => write!(f, "<{}>", s),
N3Term::Literal {
value,
datatype,
lang,
} => {
write!(f, "\"{}\"", value)?;
if let Some(dt) = datatype {
write!(f, "^^<{}>", dt)?;
}
if let Some(l) = lang {
write!(f, "@{}", l)?;
}
Ok(())
}
N3Term::BlankNode(s) => write!(f, "_:{}", s),
N3Term::Variable(s) => write!(f, "?{}", s),
N3Term::Universal(s) => write!(f, "!{}", s),
N3Term::NestedFormula(_) => write!(f, "{{ ... }}"),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum N3BuiltIn {
MathSum {
args: Vec<N3Term>,
result: N3Term,
},
MathDifference {
args: Vec<N3Term>,
result: N3Term,
},
MathProduct {
args: Vec<N3Term>,
result: N3Term,
},
MathQuotient {
args: Vec<N3Term>,
result: N3Term,
},
MathGreaterThan {
left: N3Term,
right: N3Term,
},
MathLessThan {
left: N3Term,
right: N3Term,
},
MathEqualTo {
left: N3Term,
right: N3Term,
},
StringConcatenation {
args: Vec<N3Term>,
result: N3Term,
},
StringLength {
input: N3Term,
result: N3Term,
},
StringContains {
subject: N3Term,
substring: N3Term,
},
LogImplies {
antecedent: Box<N3Formula>,
consequent: Box<N3Formula>,
},
LogConcludes {
graph: N3Term,
formula: Box<N3Formula>,
},
LogEqual {
left: N3Term,
right: N3Term,
},
LogNotEqual {
left: N3Term,
right: N3Term,
},
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Triple {
pub subject: String,
pub predicate: String,
pub object: String,
}
impl Triple {
pub fn new(s: impl Into<String>, p: impl Into<String>, o: impl Into<String>) -> Self {
Self {
subject: s.into(),
predicate: p.into(),
object: o.into(),
}
}
}
pub type Bindings = HashMap<String, N3Term>;