From d98a901c2722eebd5b23f31a42dea9d506a1c5a1 Mon Sep 17 00:00:00 2001 From: Matthias Meissner Date: Tue, 28 Nov 2023 12:34:28 +0100 Subject: [PATCH] add tuple terms --- nemo-python/src/lib.rs | 1 + nemo-wasm/src/lib.rs | 1 + nemo/src/model/rule_model.rs | 3 + nemo/src/model/rule_model/term.rs | 6 +- nemo/src/model/rule_model/tuple.rs | 55 +++++++++++++++++++ .../model/types/primitive_logical_value.rs | 13 ++++- 6 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 nemo/src/model/rule_model/tuple.rs diff --git a/nemo-python/src/lib.rs b/nemo-python/src/lib.rs index 94ab4cf64..e88b22d0e 100644 --- a/nemo-python/src/lib.rs +++ b/nemo-python/src/lib.rs @@ -173,6 +173,7 @@ fn constant_to_python<'a>(py: Python<'a>, v: &Constant) -> PyResult<&'a PyAny> { Ok(Py::new(py, lit)?.to_object(py).into_ref(py)) })(), Constant::MapLiteral(_map) => todo!("maps are not yet supported"), + Constant::TupleLiteral(_tuple) => todo!("tuples are not yet supported"), } } diff --git a/nemo-wasm/src/lib.rs b/nemo-wasm/src/lib.rs index fba90d9d2..a7df0ebf8 100644 --- a/nemo-wasm/src/lib.rs +++ b/nemo-wasm/src/lib.rs @@ -355,6 +355,7 @@ impl NemoResults { Constant::StringLiteral(s) => JsValue::from(s), Constant::RdfLiteral(lit) => JsValue::from(lit.to_string()), Constant::MapLiteral(_map) => todo!("maps are not yet supported"), + Constant::TupleLiteral(_tuple) => todo!("tuples are not yet supported"), }, PrimitiveLogicalValueT::String(s) => JsValue::from(String::from(s)), PrimitiveLogicalValueT::Integer(i) => JsValue::from(i64::from(i)), diff --git a/nemo/src/model/rule_model.rs b/nemo/src/model/rule_model.rs index 25ca5a18c..472242d6a 100644 --- a/nemo/src/model/rule_model.rs +++ b/nemo/src/model/rule_model.rs @@ -32,3 +32,6 @@ pub use constraint::*; mod map; pub use map::*; + +mod tuple; +pub use tuple::*; diff --git a/nemo/src/model/rule_model/term.rs b/nemo/src/model/rule_model/term.rs index 099dbef59..712e55e69 100644 --- a/nemo/src/model/rule_model/term.rs +++ b/nemo/src/model/rule_model/term.rs @@ -15,7 +15,7 @@ use crate::{ program_analysis::variable_order::VariableOrder, }; -use super::{Aggregate, Identifier, Map, NumericLiteral, RdfLiteral}; +use super::{Aggregate, Identifier, Map, NumericLiteral, RdfLiteral, Tuple}; /// Variable that can be bound to a specific value #[derive(Debug, Eq, PartialEq, Hash, Clone, PartialOrd, Ord)] @@ -84,6 +84,8 @@ pub enum Constant { RdfLiteral(RdfLiteral), /// A map literal. MapLiteral(Map), + /// A tuple literal + TupleLiteral(Tuple), } impl Constant { @@ -95,6 +97,7 @@ impl Constant { Self::StringLiteral(_) => Some(PrimitiveType::String), Self::NumericLiteral(nl) => Some(nl.primitive_type()), Self::MapLiteral(_) => None, + Self::TupleLiteral(_) => None, } } @@ -145,6 +148,7 @@ impl Display for Constant { Constant::StringLiteral(literal) => write!(f, "\"{}\"", literal), Constant::RdfLiteral(literal) => write!(f, "{}", literal), Constant::MapLiteral(term) => write!(f, "{term}"), + Constant::TupleLiteral(tuple) => write!(f, "{tuple}"), } } } diff --git a/nemo/src/model/rule_model/tuple.rs b/nemo/src/model/rule_model/tuple.rs new file mode 100644 index 000000000..2dec69690 --- /dev/null +++ b/nemo/src/model/rule_model/tuple.rs @@ -0,0 +1,55 @@ +use std::{ops::Deref, sync::Arc}; + +use super::Constant; + +/// A Tuple: a [Constant] +#[derive(Debug, Eq, PartialEq, Clone, PartialOrd, Ord)] +pub struct Tuple { + values: Arc<[Constant]>, +} + +impl Default for Tuple { + fn default() -> Self { + Self { + values: [].into_iter().collect(), + } + } +} + +impl Tuple { + /// Returns the size of the tuple. + pub fn arity(&self) -> usize { + self.values.len() + } +} + +impl Deref for Tuple { + type Target = [Constant]; + + fn deref(&self) -> &[Constant] { + &self.values + } +} + +impl FromIterator for Tuple { + fn from_iter>(iter: T) -> Self { + Self { + values: iter.into_iter().collect(), + } + } +} + +impl std::fmt::Display for Tuple { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "(")?; + f.write_str( + &self + .iter() + .map(|x| ToString::to_string(x)) + .by_ref() + .intersperse(", ".into()) + .collect::(), + )?; + write!(f, ")") + } +} diff --git a/nemo/src/model/types/primitive_logical_value.rs b/nemo/src/model/types/primitive_logical_value.rs index 2b6e1236e..6dbdd421a 100644 --- a/nemo/src/model/types/primitive_logical_value.rs +++ b/nemo/src/model/types/primitive_logical_value.rs @@ -10,7 +10,8 @@ use nemo_physical::{ }; use crate::model::{ - Constant, Identifier, Map, NumericLiteral, RdfLiteral, XSD_DECIMAL, XSD_DOUBLE, XSD_INTEGER, + Constant, Identifier, Map, NumericLiteral, RdfLiteral, Tuple, XSD_DECIMAL, XSD_DOUBLE, + XSD_INTEGER, }; use super::{error::InvalidRuleTermConversion, primitive_types::PrimitiveType}; @@ -23,6 +24,7 @@ const DOUBLE_PREFIX: &str = "DO:"; const CONSTANT_PREFIX: &str = "CO:"; const DATATYPE_VALUE_PREFIX: &str = "DV:"; const MAP_VALUE_PREFIX: &str = "MP:"; +const TUPLE_VALUE_PREFIX: &str = "TP:"; /// The prefix used to indicate constants that are Nulls pub const LOGICAL_NULL_PREFIX: &str = "__Null#"; @@ -188,6 +190,12 @@ impl From for PhysicalString { } } +impl From for PhysicalString { + fn from(value: Tuple) -> Self { + format!("{TUPLE_VALUE_PREFIX}{value}").into() + } +} + impl From for LogicalString { fn from(value: LogicalInteger) -> Self { value.0.to_string().into() @@ -330,7 +338,8 @@ impl TryFrom for PhysicalString { Constant::RdfLiteral(RdfLiteral::DatatypeValue { value, datatype }) => { Ok(DatatypeValue(value, datatype).into()) } - Constant::MapLiteral(value) => Ok(value.into()), + Constant::MapLiteral(value) => Ok(PhysicalString::from(value)), + Constant::TupleLiteral(tuple) => Ok(PhysicalString::from(tuple)), } } }