Skip to content

Commit

Permalink
Feature/570 builtin iri (#589)
Browse files Browse the repository at this point in the history
Adds the builtin `IRI` that takes as input a plain string and casts its type to an IRI
  • Loading branch information
aannleax authored Jan 13, 2025
2 parents 95057ad + 4cea76a commit 4a45f41
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 7 deletions.
3 changes: 3 additions & 0 deletions nemo-physical/src/function/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub(crate) mod language;
pub(crate) mod numeric;
pub(crate) mod string;

use casting::CastingIntoIri;
use delegate::delegate;

use crate::{
Expand Down Expand Up @@ -132,6 +133,7 @@ pub enum UnaryFunctionEnum {
CastingIntoInteger64(CastingIntoInteger64),
CastingIntoDouble(CastingIntoDouble),
CastingIntoFloat(CastingIntoFloat),
CastingIntoIri(CastingIntoIri),
CheckIsDouble(CheckIsDouble),
CheckIsFloat(CheckIsFloat),
CheckIsInteger(CheckIsInteger),
Expand Down Expand Up @@ -167,6 +169,7 @@ impl UnaryFunction for UnaryFunctionEnum {
Self::CastingIntoInteger64(function) => function,
Self::CastingIntoFloat(function) => function,
Self::CastingIntoDouble(function) => function,
Self::CastingIntoIri(function) => function,
Self::CheckIsDouble(function) => function,
Self::CheckIsFloat(function) => function,
Self::CheckIsInteger(function) => function,
Expand Down
24 changes: 24 additions & 0 deletions nemo-physical/src/function/definitions/casting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,27 @@ impl UnaryFunction for CastingIntoDouble {
FunctionTypePropagation::KnownOutput(StorageTypeName::Double.bitset())
}
}

/// Casting of a string value into an IRI
///
/// Returns an IRI with the same content as the given string.
///
/// Returns `None` when called on values other than plain strings.
#[derive(Debug, Copy, Clone)]
pub struct CastingIntoIri;
impl UnaryFunction for CastingIntoIri {
fn evaluate(&self, parameter: AnyDataValue) -> Option<AnyDataValue> {
parameter
.to_plain_string()
.or_else(|| parameter.to_iri())
.map(AnyDataValue::new_iri)
}

fn type_propagation(&self) -> FunctionTypePropagation {
FunctionTypePropagation::KnownOutput(
StorageTypeName::Id32
.bitset()
.union(StorageTypeName::Id64.bitset()),
)
}
}
3 changes: 3 additions & 0 deletions nemo-physical/src/function/evaluation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,9 @@ mod test {

let tree_to_double = Function::casting_to_double(Function::constant(any_int(4)));
evaluate_expect(&tree_to_double, Some(any_double(4.0)));

let tree_to_iri = Function::casting_to_iri(Function::constant(any_string("test")));
evaluate_expect(&tree_to_iri, Some(any_iri("test")));
}

#[test]
Expand Down
12 changes: 11 additions & 1 deletion nemo-physical/src/function/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::datavalues::AnyDataValue;
use super::{
definitions::{
boolean::{BooleanConjunction, BooleanDisjunction, BooleanNegation},
casting::{CastingIntoDouble, CastingIntoFloat, CastingIntoInteger64},
casting::{CastingIntoDouble, CastingIntoFloat, CastingIntoInteger64, CastingIntoIri},
checktype::{
CheckIsDouble, CheckIsFloat, CheckIsInteger, CheckIsIri, CheckIsNull, CheckIsNumeric,
CheckIsString,
Expand Down Expand Up @@ -374,6 +374,16 @@ where
)
}

/// Create a tree node representing casting a plain string value into an IRI.
///
/// This evaluates to an IRI with the same content as `sub`.
pub fn casting_to_iri(sub: Self) -> Self {
Self::Unary(
UnaryFunctionEnum::CastingIntoIri(CastingIntoIri),
Box::new(sub),
)
}

/// Create a tree node representing addition between numbers.
///
/// This evaluates to the sum of the values of the
Expand Down
1 change: 1 addition & 0 deletions nemo/src/execution/planning/operations/operation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ pub(crate) fn operation_to_function_tree(
OperationKind::CastToDouble => unary!(casting_to_double, sub),
OperationKind::CastToFloat => unary!(casting_to_float, sub),
OperationKind::CastToInteger => unary!(casting_to_integer64, sub),
OperationKind::CastToIRI => unary!(casting_to_iri, sub),
OperationKind::CanonicalString => unary!(canonical_string, sub),
OperationKind::CheckIsInteger => unary!(check_is_integer, sub),
OperationKind::CheckIsFloat => unary!(check_is_float, sub),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,11 @@ pub enum OperationKind {
#[assoc(num_arguments = OperationNumArguments::Unary)]
#[assoc(return_type = ValueType::Number)]
CastToInteger,
/// Cast to IRI
#[assoc(name = function::IRI)]
#[assoc(num_arguments = OperationNumArguments::Unary)]
#[assoc(return_type = ValueType::Constant)]
CastToIRI,
/// Canonical string representation of a value
#[assoc(name = function::FULLSTR)]
#[assoc(num_arguments = OperationNumArguments::Unary)]
Expand Down Expand Up @@ -267,7 +272,7 @@ pub enum OperationKind {
#[assoc(return_type = ValueType::Number)]
NumericFloor,
/// Additive inverse of a numeric value
#[assoc(name = function::INVERSE)]
#[assoc(name = function::INVERTSIGN)]
#[assoc(num_arguments = OperationNumArguments::Unary)]
#[assoc(return_type = ValueType::Number)]
NumericNegation,
Expand Down
4 changes: 3 additions & 1 deletion nemo/src/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,8 @@ pub mod builtin {
pub(crate) const DOUBLE: &str = "DOUBLE";
/// Convert the value to a 32bit floating point number
pub(crate) const FLOAT: &str = "FLOAT";
/// Convert a plain string into an IRI
pub(crate) const IRI: &str = "IRI";
/// Compute the logarithm of the numerical value
pub(crate) const LOGARITHM: &str = "LOG";
/// Raise the numerical value to a power
Expand Down Expand Up @@ -307,7 +309,7 @@ pub mod builtin {
/// Compute the quotient of two numeric values
pub(crate) const DIVISION: &str = "DIVISION";
/// Compute the multiplicative inverse of a numeric value
pub(crate) const INVERSE: &str = "INVERSE";
pub(crate) const INVERTSIGN: &str = "INVERTSIGN";
/// Compute the logical and between boolean values
pub(crate) const AND: &str = "AND";
/// Compute the logical or between boolean values
Expand Down
10 changes: 6 additions & 4 deletions resources/testcases/arithmetic/builtins.rls
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ strings("Hello", "World").
doubles(2.0E0, 1.5E0, 0.5E0).
integers(1, 2, 3).
tagged("test"@en).
iri(constant).
null(!V) :- iri(?X).
constant(constant).
null(!V) :- constant(?X).
@import uri_strings :- csv{resource="sources/uri_strings.csv"}.

% Datatype check
Expand All @@ -15,7 +15,7 @@ result(isint, ?R) :- integers(?A, _, _), ?R = isInteger(?A).
result(isfloat, ?R) :- doubles(?A, _, _), ?R = isFloat(?A).
result(isdouble, ?R) :- doubles(?A, _, _), ?R = isDouble(?A).
result(isnumeric, ?R) :- integers(?A, _, _), ?R = isNumeric(?A).
result(isiri, ?R) :- iri(?A), ?R = isIri(?A).
result(isiri, ?R) :- constant(?A), ?R = isIri(?A).
result(isnull, ?R) :- null(?A), ?R = isNull(?A).

% String representation
Expand All @@ -31,17 +31,19 @@ result(fullstring, ?R) :- tagged(?A), ?R = fullStr(?A).
% Get language tag
result(tag, ?R) :- tagged(?L), ?R = LANG(?L).

% Numeric casts
% Casts
cast(3.0).
cast(4.2).
cast(5).
cast(test).
cast("2023"^^xsd:gYear).
cast("40").
cast("https://example.org").

result(int, ?R) :- cast(?A), ?R = INT(?A).
result(float, ?R) :- cast(?A), ?R = FLOAT(?A).
result(double, ?R) :- cast(?A), ?R = DOUBLE(?A).
result(iri, ?R) :- cast(?A), ?R = IRI(?A).

% Cast within numeric operations

Expand Down
3 changes: 3 additions & 0 deletions resources/testcases/arithmetic/builtins/result.csv
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ double,"""4.2""^^<http://www.w3.org/2001/XMLSchema#double>"
double,"""5""^^<http://www.w3.org/2001/XMLSchema#double>"
double,"""40""^^<http://www.w3.org/2001/XMLSchema#double>"
double,"""2023""^^<http://www.w3.org/2001/XMLSchema#double>"
iri,https://example.org
iri,40
iri,test
mixedsum,"""6.5""^^<http://www.w3.org/2001/XMLSchema#double>"
round,5
round,"""3""^^<http://www.w3.org/2001/XMLSchema#double>"
Expand Down

0 comments on commit 4a45f41

Please sign in to comment.