[SPARQL] Makes clear in the type system that blank node are considered as variables

pull/10/head
Tpt 6 years ago
parent 63d88f2297
commit a6e9b10f9e
  1. 175
      src/sparql/algebra.rs
  2. 149
      src/sparql/model.rs

@ -5,6 +5,163 @@ use std::collections::BTreeSet;
use std::fmt;
use std::ops::Add;
use utils::Escaper;
use uuid::Uuid;
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum Variable {
Variable { name: String },
BlankNode { id: Uuid },
Internal { id: Uuid },
}
impl Variable {
pub fn new(name: impl Into<String>) -> Self {
Variable::Variable { name: name.into() }
}
pub fn has_name(&self) -> bool {
match self {
Variable::Variable { .. } => true,
_ => false,
}
}
}
impl fmt::Display for Variable {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Variable::Variable { name } => write!(f, "?{}", name),
Variable::BlankNode { id } => write!(f, "_:{}", id.simple()),
Variable::Internal { id } => write!(f, "?{}", id.simple()),
}
}
}
impl Default for Variable {
fn default() -> Self {
Variable::Internal { id: Uuid::new_v4() }
}
}
impl From<BlankNode> for Variable {
fn from(blank_node: BlankNode) -> Self {
Variable::BlankNode { id: *blank_node }
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum NamedNodeOrVariable {
NamedNode(NamedNode),
Variable(Variable),
}
impl fmt::Display for NamedNodeOrVariable {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
NamedNodeOrVariable::NamedNode(node) => write!(f, "{}", node),
NamedNodeOrVariable::Variable(var) => write!(f, "{}", var),
}
}
}
impl From<NamedNode> for NamedNodeOrVariable {
fn from(node: NamedNode) -> Self {
NamedNodeOrVariable::NamedNode(node)
}
}
impl From<Variable> for NamedNodeOrVariable {
fn from(var: Variable) -> Self {
NamedNodeOrVariable::Variable(var)
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum TermOrVariable {
NamedNode(NamedNode),
Literal(Literal),
Variable(Variable),
}
impl fmt::Display for TermOrVariable {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
TermOrVariable::NamedNode(node) => write!(f, "{}", node),
TermOrVariable::Literal(node) => write!(f, "{}", node),
TermOrVariable::Variable(var) => write!(f, "{}", var),
}
}
}
impl From<NamedNode> for TermOrVariable {
fn from(node: NamedNode) -> Self {
TermOrVariable::NamedNode(node)
}
}
impl From<BlankNode> for TermOrVariable {
fn from(node: BlankNode) -> Self {
TermOrVariable::Variable(node.into())
}
}
impl From<Literal> for TermOrVariable {
fn from(literal: Literal) -> Self {
TermOrVariable::Literal(literal)
}
}
impl From<Variable> for TermOrVariable {
fn from(var: Variable) -> Self {
TermOrVariable::Variable(var)
}
}
impl From<Term> for TermOrVariable {
fn from(term: Term) -> Self {
match term {
Term::NamedNode(node) => TermOrVariable::NamedNode(node),
Term::BlankNode(node) => TermOrVariable::Variable(node.into()),
Term::Literal(literal) => TermOrVariable::Literal(literal),
}
}
}
impl From<NamedNodeOrVariable> for TermOrVariable {
fn from(element: NamedNodeOrVariable) -> Self {
match element {
NamedNodeOrVariable::NamedNode(node) => TermOrVariable::NamedNode(node),
NamedNodeOrVariable::Variable(var) => TermOrVariable::Variable(var),
}
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub struct TriplePattern {
pub subject: TermOrVariable,
pub predicate: NamedNodeOrVariable,
pub object: TermOrVariable,
}
impl TriplePattern {
pub fn new(
subject: impl Into<TermOrVariable>,
predicate: impl Into<NamedNodeOrVariable>,
object: impl Into<TermOrVariable>,
) -> Self {
Self {
subject: subject.into(),
predicate: predicate.into(),
object: object.into(),
}
}
}
impl fmt::Display for TriplePattern {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {} {}", self.subject, self.predicate, self.object)
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum PropertyPath {
@ -739,21 +896,21 @@ impl MultiSetPattern {
match pattern {
TripleOrPathPattern::Triple(tp) => {
if let TermOrVariable::Variable(ref s) = tp.subject {
vars.insert(s);
adds_if_has_name(vars, s);
}
if let NamedNodeOrVariable::Variable(ref p) = tp.predicate {
vars.insert(p);
adds_if_has_name(vars, p);
}
if let TermOrVariable::Variable(ref o) = tp.object {
vars.insert(o);
adds_if_has_name(vars, o);
}
}
TripleOrPathPattern::Path(ppp) => {
if let TermOrVariable::Variable(ref s) = ppp.subject {
vars.insert(s);
adds_if_has_name(vars, s);
}
if let TermOrVariable::Variable(ref o) = ppp.object {
vars.insert(o);
adds_if_has_name(vars, o);
}
}
}
@ -775,7 +932,7 @@ impl MultiSetPattern {
MultiSetPattern::Graph(_, p) => p.add_visible_variables(vars),
MultiSetPattern::Extend(p, v, _) => {
p.add_visible_variables(vars);
vars.insert(&v);
adds_if_has_name(vars, &v);
}
MultiSetPattern::Minus(a, _) => a.add_visible_variables(vars),
MultiSetPattern::ToMultiSet(l) => l.add_visible_variables(vars),
@ -785,6 +942,12 @@ impl MultiSetPattern {
}
}
fn adds_if_has_name<'a>(vars: &mut BTreeSet<&'a Variable>, var: &'a Variable) {
if var.has_name() {
vars.insert(var);
}
}
struct SparqlMultiSetPattern<'a>(&'a MultiSetPattern);
impl<'a> fmt::Display for SparqlMultiSetPattern<'a> {

@ -1,146 +1,8 @@
use model::*;
use sparql::algebra::TermOrVariable;
use sparql::algebra::Variable;
use std::collections::BTreeMap;
use std::fmt;
use uuid::Uuid;
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub struct Variable {
name: String,
}
impl Variable {
pub fn new(name: impl Into<String>) -> Self {
Self { name: name.into() }
}
}
impl fmt::Display for Variable {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "?{}", self.name)
}
}
impl Default for Variable {
fn default() -> Self {
Self {
name: Uuid::new_v4().simple().to_string(),
}
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum NamedNodeOrVariable {
NamedNode(NamedNode),
Variable(Variable),
}
impl fmt::Display for NamedNodeOrVariable {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
NamedNodeOrVariable::NamedNode(node) => write!(f, "{}", node),
NamedNodeOrVariable::Variable(var) => write!(f, "{}", var),
}
}
}
impl From<NamedNode> for NamedNodeOrVariable {
fn from(node: NamedNode) -> Self {
NamedNodeOrVariable::NamedNode(node)
}
}
impl From<Variable> for NamedNodeOrVariable {
fn from(var: Variable) -> Self {
NamedNodeOrVariable::Variable(var)
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub enum TermOrVariable {
Term(Term),
Variable(Variable),
}
impl fmt::Display for TermOrVariable {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
TermOrVariable::Term(node) => write!(f, "{}", node),
TermOrVariable::Variable(var) => write!(f, "{}", var),
}
}
}
impl From<NamedNode> for TermOrVariable {
fn from(node: NamedNode) -> Self {
TermOrVariable::Term(node.into())
}
}
impl From<BlankNode> for TermOrVariable {
fn from(node: BlankNode) -> Self {
TermOrVariable::Term(node.into())
}
}
impl From<Literal> for TermOrVariable {
fn from(literal: Literal) -> Self {
TermOrVariable::Term(literal.into())
}
}
impl From<NamedOrBlankNode> for TermOrVariable {
fn from(node: NamedOrBlankNode) -> Self {
TermOrVariable::Term(node.into())
}
}
impl From<Term> for TermOrVariable {
fn from(node: Term) -> Self {
TermOrVariable::Term(node)
}
}
impl From<Variable> for TermOrVariable {
fn from(var: Variable) -> Self {
TermOrVariable::Variable(var)
}
}
impl From<NamedNodeOrVariable> for TermOrVariable {
fn from(element: NamedNodeOrVariable) -> Self {
match element {
NamedNodeOrVariable::NamedNode(node) => TermOrVariable::Term(node.into()),
NamedNodeOrVariable::Variable(var) => TermOrVariable::Variable(var),
}
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub struct TriplePattern {
pub subject: TermOrVariable,
pub predicate: NamedNodeOrVariable,
pub object: TermOrVariable,
}
impl TriplePattern {
pub fn new(
subject: impl Into<TermOrVariable>,
predicate: impl Into<NamedNodeOrVariable>,
object: impl Into<TermOrVariable>,
) -> Self {
Self {
subject: subject.into(),
predicate: predicate.into(),
object: object.into(),
}
}
}
impl fmt::Display for TriplePattern {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {} {}", self.subject, self.predicate, self.object)
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub struct Binding(BTreeMap<Variable, Term>);
@ -154,10 +16,11 @@ impl Binding {
self.0.get(key)
}
pub fn get_or_constant<'a>(&'a self, key: &'a TermOrVariable) -> Option<&'a Term> {
pub fn get_or_constant<'a>(&'a self, key: &'a TermOrVariable) -> Option<Term> {
match key {
TermOrVariable::Term(t) => Some(t),
TermOrVariable::Variable(v) => self.get(v),
TermOrVariable::NamedNode(node) => Some(node.clone().into()),
TermOrVariable::Literal(literal) => Some(literal.clone().into()),
TermOrVariable::Variable(v) => self.get(v).cloned(),
}
}

Loading…
Cancel
Save