diff --git a/.gitignore b/.gitignore index bee8a64..083d732 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ __pycache__ +.idea diff --git a/spec/dev.html b/spec/dev.html new file mode 100644 index 0000000..40d1d0f --- /dev/null +++ b/spec/dev.html @@ -0,0 +1,135 @@ + + + +
++ Draft Community Group Report + +
++ Copyright + © + 2021-2025 + + the Contributors to the RML-FNML + Specification, published by the + Knowledge Graph Construction Community Group under the + W3C Community Contributor License Agreement (CLA). A human-readable + summary + is available. + +
+Referenced in:
+Referenced in:
+Referenced in:
+Referenced in:
+Referenced in:
+Referenced in:
+Referenced in:
+Referenced in:
+ +Referenced in:
+Referenced in:
+Referenced in:
+Referenced in:
+Referenced in:
+RML+FnO is an approach to provide for data transformations when generating knowledge graphs +from (semi-)structured data using the RDF Mapping Language (RML).
+In RML+FnO, data transformations are defined declaratively, +supporting the Function Ontology (FnO).
+This approach is not case-specific: +data transformations are independent of their implementation and thus interoperable, +while the functions are decoupled and reusable. +This allows developers to improve the generation framework +independent from the contributors that focus on generating the knowledge graphs.
++ This specification was published by the + Knowledge Graph Construction Community Group. It is not a W3C Standard nor is it + on the W3C Standards Track. + + Please note that under the + W3C Community Contributor License Agreement (CLA) + there is a limited opt-out and other conditions apply. + + Learn more about + W3C Community and Business Groups. +
+ GitHub Issues are preferred for + discussion of this specification. + + +
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
+ The key words MAY and MUST in this document + are to be interpreted as described in + BCP 14 + [RFC2119] [RFC8174] + when, and only when, they appear in all + capitals, as shown here. +
Mapping languages allow us to define how knowledge graphs are generated from (semi-)structured data, +but only if the original data values can be used as-is. +Complex data transformations in mapping languages typically are +either implemented as custom solutions, +or are done by systems separate from the mapping process. +The former data transformations remain case-specific, often coupled with the mapping, +whereas the latter is not reusable across systems.
+For example, we have a data source where all names are lowercase, +but we want the resulting knowledge to have uppercase values. +The following RML Mapping contains the descriptions to generate a knowledge graph from a data source, +but no data transformations.
+[RML]-independent defintions:
+function int sum(int a, int b) throws StackOverFlowException, namely,
+the Function sum has two input parameters, int a and int b, and returns an int or throws a StackOverFlowException.sum(2, 4) = 6 is an execution,
+where 2 is bound to the a Parameter, 4 is bound to the b Parameter, and 6 is bound as Return value.Definitions taken from [RML] or R2RML: RDB to RDF Mapping Language:
+Within this specification, the Expression Map definition is extended by adding new possible properties and thus also a new type of Expression Map. +The change is included below with changes highlighted in bold.
+An Expression Map can have the following properties:
+It is currently assumed that a Function-valued Expression Map always returns an RDF term [rdf-concepts]. +How a list of RDF terms is handled, is out of scope of this spec, but discussed at Collections and Containers in RML.
+Instead of integrating a specific set of functions in [RML], +we combine [RML] with declarative function descriptions in [FnO].
+Within [FnO], Functions and Executions are described. +Within FNML, we refer to Executions that link to specific Functions.
+Triples Maps generate output triples from input data. +We use an intermediate Function-valued Expression Map to use a specific output (via a Return Map) of a Function Execution. +That Function Execution specifies which [FnO] function to use (via a Function Map) +and uses Inputs to link input data (via regular [RML] Term Maps) +to Parameters (via Parameter Maps).
+If an execution returns multiple returning outputs (eg, a result and a status code), +by referring to the same execution, +you can use both outputs in different locations of the same mapping. +If you leave out the intermediate Function-valued Expression Map, you don't allow for reuse, +which means that you cannot specify the difference between +'using 2 outputs from one execution' vs 'use a different output from 2 different executions'.
+We use Example 1, +where we want to perform an uppercase operation to a set of fields.
+The FnO description of the function toUppercase is as follows:
+@prefix dcterms: <http://purl.org/dc/terms/> .
+@prefix fno: <https://w3id.org/function/ontology#> .
+@prefix grel: <http://users.ugent.be/~bjdmeest/function/grel.ttl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+
+grel:toUpperCase
+ a fno:Function ;
+ fno:name "to Uppercase" ;
+ rdfs:label "to Uppercase" ;
+ dcterms:description "Returns the input with all letters in upper case." ;
+ fno:expects ( grel:valueParam ) ;
+ fno:returns ( grel:stringOut ) .
+
+grel:valueParam
+ a fno:Parameter ;
+ fno:name "input value" ;
+ rdfs:label "input value" ;
+ fno:predicate grel:valueParameter ;
+ fno:type xsd:string ;
+ fno:required "true"^^xsd:boolean .
+
+grel:stringOut
+ a fno:Output ;
+ fno:name "output string" ;
+ rdfs:label "output string" ;
+ fno:predicate grel:stringOutput ;
+ fno:type xsd:string .
+
+The execution of such a function converts a string to its uppercase sibling,
+so test becomes TEST and This is an input STRING. becomes THIS IS AN INPUT STRING..
+The latter would be described as follows using an FnO Execution description:
@prefix fno: <https://w3id.org/function/ontology#> .
+@prefix grel: <http://users.ugent.be/~bjdmeest/function/grel.ttl#> .
+@prefix : <http://example.com/> .
+
+:exe a fno:Execution ;
+ fno:executes grel:toUppercase ;
+ grel:valueParameter "This is an input STRING." ;
+ grel:stringOutput "THIS IS AN INPUT STRING." .
+
+To connect this function with the RML mapping document, we make use of FNML, see below for an example, which makes maximal use of shortcuts.
+@prefix dbo: <http://dbpedia.org/ontology/> .
+@prefix grel: <http://users.ugent.be/~bjdmeest/function/grel.ttl#> .
+@prefix rml: <http://w3id.org/rml/> .
+
+<#Person_Mapping>
+ rml:logicalSource <#LogicalSource> ;
+ rml:subjectMap <#SubjectMap> ;
+ rml:predicateObjectMap <#NameMapping> .
+
+<#NameMapping>
+ rml:predicate dbo:title ;
+ rml:objectMap [ # A function-valued expression map
+ rml:functionExecution <#Execution> ; # Link to a Function Execution
+ rml:return grel:stringOut # Specify which return of the referenced function to use, if omitted, the first specified return is used
+ ] .
+
+<#Execution> a rml:FunctionExecution ; # A new class
+ rml:function grel:toUppercase ; # Specify which FnO function
+ rml:input [ # Specify the inputs
+ a rml:Input ; # A new class
+ rml:parameter grel:valueParam ; # Specify this specific parameter
+ rml:inputValueMap [ # Link to the term map that creates the input value
+ rml:reference "name" # Specify the reference within the data source
+ ]
+ ] .
+
+The name-value is not referenced directly,
+instead, its value is used as grel:valueParam-parameter
+for the grel:toUppercase-function.
+After execution, the grel:stringOut result of that function is returned to generate the object
+within the <#NameMapping>.
+We make use of an intermediate Function-valued Expression Map so that we can reuse the returning output of an execution in multiple TermMaps.
The same example, but written without shortcuts, is as follows:
+@prefix dbo: <http://dbpedia.org/ontology/> .
+@prefix grel: <http://users.ugent.be/~bjdmeest/function/grel.ttl#> .
+@prefix rml: <http://w3id.org/rml/> .
+
+<#Person_Mapping>
+ rml:logicalSource <#LogicalSource> ; # Specify the data source
+ rml:subjectMap <#SubjectMap> ; # Specify the subject
+ rml:predicateObjectMap <#NameMapping> . # Specify the predicate-object-map
+
+<#NameMapping>
+ rml:predicate dbo:title ; # Specify the predicate
+ rml:objectMap [ # Specify the object-map: a function-valued expression map
+ rml:functionExecution <#Execution> ; # Link to a Function Execution
+ rml:returnMap [
+ a rml:ReturnMap ;
+ rml:constant grel:stringOut # Specify which return of the referenced function to use
+ ]
+ ] .
+
+<#Execution> a rml:FunctionExecution ; # A new class
+ rml:functionMap [
+ a rml:FunctionMap ;
+ rml:constant grel:toUppercase # Specify which FnO function
+ ] ;
+ rml:input # Specify the inputs
+ [
+ a rml:Input ; # A new class
+ rml:parameterMap [
+ a rml:ParameterMap ;
+ rml:constant grel:valueParam ; # Specify this specific parameter
+ ] ;
+ rml:inputValueMap [ # Link to the term map that creates the input value
+ a rml:TermMap ;
+ rml:reference "name" # Specify the reference within the data source
+ ]
+ ] .
+
+We use terms defined in the FNML ontology to link [RML] with [FNO].
+The ontology namespace is http://w3id.org/rml/,
+the preferred prefix is rml:.
+See below for how FNML introduced terms align with RML Core.
+ A Function-valued Expression Map is an Expression Map that is represented by a resource that has exactly one rml:functionExecution.
+The value of the rml:functionExecution property must be a valid Execution.
As a consequence, the default [RML] processing is extended,
+specifically concerning the default term type depending on whether the Term Map is an Object Map or not,
+namely, the Function-valued Expression Maps default term type is rml:Literal.
+The change is included below with changes highlighted in bold.
If the Term Map does not have a rml:termType property, then its term type is:
rml:Literal, if it is an Object Map and at least one of the following conditions is true:rml:languageMap and/or rml:language property (and thus a Language Map and/or a specified language tag).rml:datatype property (and thus a specified datatype).rml:IRI, otherwise.A Function-valued Expression Map MUST have exactly one rml:functionExecution relation.
+Further, it MAY have following relations specified:
rml:termType: for processing, see paragraph aboverml:language OR rml:languageMap OR rml:datatype: for processing, see RML Language Tags and RML Typed Literalsrml:return: this relationship MUST refer to exactly one of the Returns as specified by the Function. This signifies which result of the execution to use. The default value is the first Return value as specified by the Function.A proper term map definition in RML is pending.
+For now, we refer to the R2RML spec, but it is assumed these references will be updated based on the evolution of RML.
+This also means that all changes to existing definitions such as term type etc. are complementary to this specification.
See Return map.
+See Function Execution.
+ + +See Function map.
+See Input.
+See Parameter map.
+Links function-valued expression map with Function Execution.
+Domain: rml:ExpressionMap
+Range: rml:FunctionExecution
+Links function-valued expression map with Return map.
+Domain: rml:ExpressionMap
+Range: rml:ReturnMap
+constant expression shortcut property of rml:returnMap.
+Links a Function Execution with Function.
+Domain: rml:FunctionExecution
+Range: rml:FunctionMap
+constant expression shortcut property of rml:functionMap.
+Links Input with Parameter map.
+Domain: rml:Input
+Range: rml:ParameterMap
+constant expression shortcut property of rml:parameterMap
+Domain: rml:Input
+Range: rml:TermMap
+constant expression shortcut property of rml:inputValueMap
+When you specifically want to have join conditions, you should use functions within rml:joinCondition, +see, e.g. test case RMLFNOTC0019.
+ +As the values of a function are represented using Expression Maps, +it is possible to nest functions: you generate a term in a first function, and that term is used as an parameter value in a second function.
+For an old example, see RMLFNOTC0018.
+For now, it is unclear how to handle a nested function where that nested Triples Map contains a join condition.
+@prefix dbo: <http://dbpedia.org/ontology/> .
+@prefix grel: <http://users.ugent.be/~bjdmeest/function/grel.ttl#> .
+@prefix rml: <http://w3id.org/rml/> .
+
+<#Person_Mapping>
+ rml:logicalSource <#LogicalSource> ;
+ rml:subjectMap <#SubjectMap> ;
+ rml:predicateObjectMap <#NameMapping> .
+
+<#NameMapping>
+ rml:predicate dbo:title ;
+ rml:objectMap [
+ rml:functionExecution <#Execution> ;
+ rml:return grel:stringOut
+ ] ;
+ .
+
+<#Execution> a rml:FunctionExecution ;
+ rml:function grel:toUppercase ;
+ rml:input
+ [
+ a rml:Input ;
+ rml:parameter grel:valueParam ;
+ rml:InputValueMap [
+ rml:functionExecution <#Execution2> ; # Link to another function-valued expression map to nest functions
+ rml:return grel:stringOut
+ ]
+ ] .
+
+<#Execution2> a rml:FunctionExecution ; # First, replace spaces with dashes from the `name` reference
+ rml:function grel:string_replace ;
+ rml:input
+ [
+ a rml:Input ;
+ rml:parameter grel:valueParam ;
+ rml:InputValueMap [
+ rml:reference "name"
+ ]
+ ] ,
+ [
+ a rml:Input ;
+ rml:parameter grel:param_find ;
+ rml:inputValue " "
+ ] ,
+ [
+ a rml:Input ;
+ rml:parameter grel:param_replace ;
+ rml:inputValue "-"
+ ] .
+
+Conditions are a shortcut to make RML mappings more intuitive, but rely on existing FNML functionality.
+It is a shortcut that is applied using the rml:condition: an additional ExpressionMap predicate.
+To be able to use this shortcut, conforming mapping engines MUST support following functions:
+ isNotNull and IF are defined below, rest is an excercise for the reader. + The actual FnO definitions are TODO. +
@prefix dbo: <http://dbpedia.org/ontology/> .
+@prefix fns: <http://example.com/fns#> .
+@prefix rml: <http://w3id.org/rml/> .
+
+<#Person_Mapping>
+ rml:logicalSource <#LogicalSource> ;
+ rml:subjectMap <#SubjectMap> ;
+ rml:predicateObjectMap <#NameMapping> .
+
+<#NameMapping>
+ rml:predicate dbo:title ;
+ # A condition can be defined in any expression map
+ rml:objectMap [
+ # new predicate that links to a function-valued expression map,
+ # that function MUST return a boolean
+ rml:condition [
+ rml:functionExecution [
+ # isNotNull(parameter: X) / definition: X != NULL ? TRUE : FALSE ;
+ rml:function fns:isNotNull ;
+ rml:input [
+ # The parameter that is checked for NULL
+ rml:parameter fns:parameter ;
+ rml:inputValueMap [
+ rml:reference "name"
+ ]
+ ]
+ ] ;
+ rml:return fns:boolOut # if fno:boolOut is the first specified return, this triple can be ommitted.
+ ] ;
+ # The actual expression used if the condition returns TRUE
+ rml:constant "[a filled in title]"
+ ] .
+
+This is actually a shortcut to the following
+@prefix dbo: <http://dbpedia.org/ontology/> .
+@prefix fns: <http://example.com/fns#> .
+@prefix rml: <http://w3id.org/rml/> .
+
+<#Person_Mapping>
+ rml:logicalSource <#LogicalSource> ;
+ rml:subjectMap <#SubjectMap> ;
+ rml:predicateObjectMap <#NameMappingExtended> .
+
+<#NameMappingExtended>
+ rml:predicate dbo:title ;
+ rml:objectMap [
+ rml:functionExecution [
+ # IF(bool: X, expression: Y)
+ # Function definition: X === TRUE ? Y : NULL
+ rml:function fns:IF ;
+ rml:input [
+ # = original condition function
+ rml:parameter fns:boolParameter ;
+ rml:inputValueMap [
+ rml:functionExecution [
+ rml:function fns:isNotNull ;
+ rml:input [
+ rml:parameter fns:parameter ;
+ rml:inputValueMap [
+ rml:reference "name"
+ ]
+ ]
+ ]
+ ]
+ ] , [
+ # = original expression
+ rml:parameter fns:expressionParameter ;
+ rml:inputValueMap [
+ rml:constant "[a filled in title]"
+ ]
+ ]
+ ] ;
+ ] .
+# Any custom function can be used,
+# or nested functions (eg AND/OR),
+# depending on what the engines support
+
++ Draft Community Group Report + +
++ Copyright + © + 2021-2025 + + the Contributors to the RML-FNML + Specification, published by the + Knowledge Graph Construction Community Group under the + W3C Community Contributor License Agreement (CLA). A human-readable + summary + is available. + +
+Referenced in:
+Referenced in:
+Referenced in:
+Referenced in:
+Referenced in:
+Referenced in:
+Referenced in:
+Referenced in:
+ +Referenced in:
+Referenced in:
+Referenced in:
+Referenced in:
+Referenced in:
+RML+FnO is an approach to provide for data transformations when generating knowledge graphs +from (semi-)structured data using the RDF Mapping Language (RML).
+In RML+FnO, data transformations are defined declaratively, +supporting the Function Ontology (FnO).
+This approach is not case-specific: +data transformations are independent of their implementation and thus interoperable, +while the functions are decoupled and reusable. +This allows developers to improve the generation framework +independent from the contributors that focus on generating the knowledge graphs.
++ This specification was published by the + Knowledge Graph Construction Community Group. It is not a W3C Standard nor is it + on the W3C Standards Track. + + Please note that under the + W3C Community Contributor License Agreement (CLA) + there is a limited opt-out and other conditions apply. + + Learn more about + W3C Community and Business Groups. +
+ GitHub Issues are preferred for + discussion of this specification. + + +
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
+ The key words MAY and MUST in this document + are to be interpreted as described in + BCP 14 + [RFC2119] [RFC8174] + when, and only when, they appear in all + capitals, as shown here. +
Mapping languages allow us to define how knowledge graphs are generated from (semi-)structured data, +but only if the original data values can be used as-is. +Complex data transformations in mapping languages typically are +either implemented as custom solutions, +or are done by systems separate from the mapping process. +The former data transformations remain case-specific, often coupled with the mapping, +whereas the latter is not reusable across systems.
+For example, we have a data source where all names are lowercase, +but we want the resulting knowledge to have uppercase values. +The following RML Mapping contains the descriptions to generate a knowledge graph from a data source, +but no data transformations.
+@prefix dbo: <http://dbpedia.org/ontology/> .
+@prefix rml: <http://w3id.org/rml/> .
+
+<#Person_Mapping>
+ rml:logicalSource <#LogicalSource> ; # Specify the data source
+ rml:subjectMap <#SubjectMap> ; # Specify the subject
+ rml:predicateObjectMap [ # Specify the predicate-object-map
+ rml:predicate dbo:title ; # Specify the predicate
+ rml:objectMap [ # Specify the object-map
+ rml:reference "name" # Specify the reference within the data source
+ ]
+ ] .
+
+[RML]-independent defintions:
+function int sum(int a, int b) throws StackOverFlowException, namely,
+the Function sum has two input parameters, int a and int b, and returns an int or throws a StackOverFlowException.sum(2, 4) = 6 is an execution,
+where 2 is bound to the a Parameter, 4 is bound to the b Parameter, and 6 is bound as Return value.Definitions taken from [RML] or R2RML: RDB to RDF Mapping Language:
+Within this specification, the Expression Map definition is extended by adding new possible properties and thus also a new type of Expression Map. +The change is included below with changes highlighted in bold.
+An Expression Map can have the following properties:
+It is currently assumed that a Function-valued Expression Map always returns an RDF term [rdf-concepts]. +How a list of RDF terms is handled, is out of scope of this spec, but discussed at Collections and Containers in RML.
+Instead of integrating a specific set of functions in [RML], +we combine [RML] with declarative function descriptions in [FnO].
+Within [FnO], Functions and Executions are described. +Within FNML, we refer to Executions that link to specific Functions.
+Triples Maps generate output triples from input data. +We use an intermediate Function-valued Expression Map to use a specific output (via a Return Map) of a Function Execution. +That Function Execution specifies which [FnO] function to use (via a Function Map) +and uses Inputs to link input data (via regular [RML] Term Maps) +to Parameters (via Parameter Maps).
+If an execution returns multiple returning outputs (eg, a result and a status code), +by referring to the same execution, +you can use both outputs in different locations of the same mapping. +If you leave out the intermediate Function-valued Expression Map, you don't allow for reuse, +which means that you cannot specify the difference between +'using 2 outputs from one execution' vs 'use a different output from 2 different executions'.
+We use Example 1, +where we want to perform an uppercase operation to a set of fields.
+The FnO description of the function toUppercase is as follows:
+@prefix dcterms: <http://purl.org/dc/terms/> .
+@prefix fno: <https://w3id.org/function/ontology#> .
+@prefix grel: <http://users.ugent.be/~bjdmeest/function/grel.ttl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+
+grel:toUpperCase
+ a fno:Function ;
+ fno:name "to Uppercase" ;
+ rdfs:label "to Uppercase" ;
+ dcterms:description "Returns the input with all letters in upper case." ;
+ fno:expects ( grel:valueParam ) ;
+ fno:returns ( grel:stringOut ) .
+
+grel:valueParam
+ a fno:Parameter ;
+ fno:name "input value" ;
+ rdfs:label "input value" ;
+ fno:predicate grel:valueParameter ;
+ fno:type xsd:string ;
+ fno:required "true"^^xsd:boolean .
+
+grel:stringOut
+ a fno:Output ;
+ fno:name "output string" ;
+ rdfs:label "output string" ;
+ fno:predicate grel:stringOutput ;
+ fno:type xsd:string .
+
+The execution of such a function converts a string to its uppercase sibling,
+so test becomes TEST and This is an input STRING. becomes THIS IS AN INPUT STRING..
+The latter would be described as follows using an FnO Execution description:
@prefix fno: <https://w3id.org/function/ontology#> .
+@prefix grel: <http://users.ugent.be/~bjdmeest/function/grel.ttl#> .
+@prefix : <http://example.com/> .
+
+:exe a fno:Execution ;
+ fno:executes grel:toUppercase ;
+ grel:valueParameter "This is an input STRING." ;
+ grel:stringOutput "THIS IS AN INPUT STRING." .
+
+To connect this function with the RML mapping document, we make use of FNML, see below for an example, which makes maximal use of shortcuts.
+@prefix dbo: <http://dbpedia.org/ontology/> .
+@prefix grel: <http://users.ugent.be/~bjdmeest/function/grel.ttl#> .
+@prefix rml: <http://w3id.org/rml/> .
+
+<#Person_Mapping>
+ rml:logicalSource <#LogicalSource> ;
+ rml:subjectMap <#SubjectMap> ;
+ rml:predicateObjectMap <#NameMapping> .
+
+<#NameMapping>
+ rml:predicate dbo:title ;
+ rml:objectMap [ # A function-valued expression map
+ rml:functionExecution <#Execution> ; # Link to a Function Execution
+ rml:return grel:stringOut # Specify which return of the referenced function to use, if omitted, the first specified return is used
+ ] .
+
+<#Execution> a rml:FunctionExecution ; # A new class
+ rml:function grel:toUppercase ; # Specify which FnO function
+ rml:input [ # Specify the inputs
+ a rml:Input ; # A new class
+ rml:parameter grel:valueParam ; # Specify this specific parameter
+ rml:inputValueMap [ # Link to the term map that creates the input value
+ rml:reference "name" # Specify the reference within the data source
+ ]
+ ] .
+
+The name-value is not referenced directly,
+instead, its value is used as grel:valueParam-parameter
+for the grel:toUppercase-function.
+After execution, the grel:stringOut result of that function is returned to generate the object
+within the <#NameMapping>.
+We make use of an intermediate Function-valued Expression Map so that we can reuse the returning output of an execution in multiple TermMaps.
The same example, but written without shortcuts, is as follows:
+@prefix dbo: <http://dbpedia.org/ontology/> .
+@prefix grel: <http://users.ugent.be/~bjdmeest/function/grel.ttl#> .
+@prefix rml: <http://w3id.org/rml/> .
+
+<#Person_Mapping>
+ rml:logicalSource <#LogicalSource> ; # Specify the data source
+ rml:subjectMap <#SubjectMap> ; # Specify the subject
+ rml:predicateObjectMap <#NameMapping> . # Specify the predicate-object-map
+
+<#NameMapping>
+ rml:predicate dbo:title ; # Specify the predicate
+ rml:objectMap [ # Specify the object-map: a function-valued expression map
+ rml:functionExecution <#Execution> ; # Link to a Function Execution
+ rml:returnMap [
+ a rml:ReturnMap ;
+ rml:constant grel:stringOut # Specify which return of the referenced function to use
+ ]
+ ] .
+
+<#Execution> a rml:FunctionExecution ; # A new class
+ rml:functionMap [
+ a rml:FunctionMap ;
+ rml:constant grel:toUppercase # Specify which FnO function
+ ] ;
+ rml:input # Specify the inputs
+ [
+ a rml:Input ; # A new class
+ rml:parameterMap [
+ a rml:ParameterMap ;
+ rml:constant grel:valueParam ; # Specify this specific parameter
+ ] ;
+ rml:inputValueMap [ # Link to the term map that creates the input value
+ a rml:TermMap ;
+ rml:reference "name" # Specify the reference within the data source
+ ]
+ ] .
+
+We use terms defined in the FNML ontology to link [RML] with [FNO].
+The ontology namespace is http://w3id.org/rml/,
+the preferred prefix is rml:.
+See below for how FNML introduced terms align with RML Core.
+ A Function-valued Expression Map is an Expression Map that is represented by a resource that has exactly one rml:functionExecution.
+The value of the rml:functionExecution property must be a valid Execution.
As a consequence, the default [RML] processing is extended,
+specifically concerning the default term type depending on whether the Term Map is an Object Map or not,
+namely, the Function-valued Expression Maps default term type is rml:Literal.
+The change is included below with changes highlighted in bold.
If the Term Map does not have a rml:termType property, then its term type is:
rml:Literal, if it is an Object Map and at least one of the following conditions is true:rml:languageMap and/or rml:language property (and thus a Language Map and/or a specified language tag).rml:datatype property (and thus a specified datatype).rml:IRI, otherwise.A Function-valued Expression Map MUST have exactly one rml:functionExecution relation.
+Further, it MAY have following relations specified:
rml:termType: for processing, see paragraph aboverml:language OR rml:languageMap OR rml:datatype: for processing, see RML Language Tags and RML Typed Literalsrml:return: this relationship MUST refer to exactly one of the Returns as specified by the Function. This signifies which result of the execution to use. The default value is the first Return value as specified by the Function.A proper term map definition in RML is pending.
+For now, we refer to the R2RML spec, but it is assumed these references will be updated based on the evolution of RML.
+This also means that all changes to existing definitions such as term type etc. are complementary to this specification.
See Return map.
+See Function Execution.
+ + +See Function map.
+See Input.
+See Parameter map.
+Links function-valued expression map with Function Execution.
+Domain: rml:ExpressionMap
+Range: rml:FunctionExecution
+Links function-valued expression map with Return map.
+Domain: rml:ExpressionMap
+Range: rml:ReturnMap
+constant expression shortcut property of rml:returnMap.
+Links a Function Execution with Function.
+Domain: rml:FunctionExecution
+Range: rml:FunctionMap
+constant expression shortcut property of rml:functionMap.
+Links Input with Parameter map.
+Domain: rml:Input
+Range: rml:ParameterMap
+constant expression shortcut property of rml:parameterMap
+Domain: rml:Input
+Range: rml:TermMap
+constant expression shortcut property of rml:inputValueMap
+When you specifically want to have join conditions, you should use functions within rml:joinCondition, +see, e.g. test case RMLFNOTC0019.
+ +As the values of a function are represented using Expression Maps, +it is possible to nest functions: you generate a term in a first function, and that term is used as an parameter value in a second function.
+For an old example, see RMLFNOTC0018.
+For now, it is unclear how to handle a nested function where that nested Triples Map contains a join condition.
+@prefix dbo: <http://dbpedia.org/ontology/> .
+@prefix grel: <http://users.ugent.be/~bjdmeest/function/grel.ttl#> .
+@prefix rml: <http://w3id.org/rml/> .
-
+<#Person_Mapping>
+ rml:logicalSource <#LogicalSource> ;
+ rml:subjectMap <#SubjectMap> ;
+ rml:predicateObjectMap <#NameMapping> .
-
+<#NameMapping>
+ rml:predicate dbo:title ;
+ rml:objectMap [
+ rml:functionExecution <#Execution> ;
+ rml:return grel:stringOut
+ ] ;
+ .
-
+<#Execution> a rml:FunctionExecution ;
+ rml:function grel:toUppercase ;
+ rml:input
+ [
+ a rml:Input ;
+ rml:parameter grel:valueParam ;
+ rml:InputValueMap [
+ rml:functionExecution <#Execution2> ; # Link to another function-valued expression map to nest functions
+ rml:return grel:stringOut
+ ]
+ ] .
-
+<#Execution2> a rml:FunctionExecution ; # First, replace spaces with dashes from the `name` reference
+ rml:function grel:string_replace ;
+ rml:input
+ [
+ a rml:Input ;
+ rml:parameter grel:valueParam ;
+ rml:InputValueMap [
+ rml:reference "name"
+ ]
+ ] ,
+ [
+ a rml:Input ;
+ rml:parameter grel:param_find ;
+ rml:inputValue " "
+ ] ,
+ [
+ a rml:Input ;
+ rml:parameter grel:param_replace ;
+ rml:inputValue "-"
+ ] .
+
+Conditions are a shortcut to make RML mappings more intuitive, but rely on existing FNML functionality.
+It is a shortcut that is applied using the rml:condition: an additional ExpressionMap predicate.
+To be able to use this shortcut, conforming mapping engines MUST support following functions:
+ isNotNull and IF are defined below, rest is an excercise for the reader. + The actual FnO definitions are TODO. +
@prefix dbo: <http://dbpedia.org/ontology/> .
+@prefix fns: <http://example.com/fns#> .
+@prefix rml: <http://w3id.org/rml/> .
-
+<#Person_Mapping>
+ rml:logicalSource <#LogicalSource> ;
+ rml:subjectMap <#SubjectMap> ;
+ rml:predicateObjectMap <#NameMapping> .
-
+<#NameMapping>
+ rml:predicate dbo:title ;
+ # A condition can be defined in any expression map
+ rml:objectMap [
+ # new predicate that links to a function-valued expression map,
+ # that function MUST return a boolean
+ rml:condition [
+ rml:functionExecution [
+ # isNotNull(parameter: X) / definition: X != NULL ? TRUE : FALSE ;
+ rml:function fns:isNotNull ;
+ rml:input [
+ # The parameter that is checked for NULL
+ rml:parameter fns:parameter ;
+ rml:inputValueMap [
+ rml:reference "name"
+ ]
+ ]
+ ] ;
+ rml:return fns:boolOut # if fno:boolOut is the first specified return, this triple can be ommitted.
+ ] ;
+ # The actual expression used if the condition returns TRUE
+ rml:constant "[a filled in title]"
+ ] .
+
+This is actually a shortcut to the following
+@prefix dbo: <http://dbpedia.org/ontology/> .
+@prefix fns: <http://example.com/fns#> .
+@prefix rml: <http://w3id.org/rml/> .
+
+<#Person_Mapping>
+ rml:logicalSource <#LogicalSource> ;
+ rml:subjectMap <#SubjectMap> ;
+ rml:predicateObjectMap <#NameMappingExtended> .
+
+<#NameMappingExtended>
+ rml:predicate dbo:title ;
+ rml:objectMap [
+ rml:functionExecution [
+ # IF(bool: X, expression: Y)
+ # Function definition: X === TRUE ? Y : NULL
+ rml:function fns:IF ;
+ rml:input [
+ # = original condition function
+ rml:parameter fns:boolParameter ;
+ rml:inputValueMap [
+ rml:functionExecution [
+ rml:function fns:isNotNull ;
+ rml:input [
+ rml:parameter fns:parameter ;
+ rml:inputValueMap [
+ rml:reference "name"
+ ]
+ ]
+ ]
+ ]
+ ] , [
+ # = original expression
+ rml:parameter fns:expressionParameter ;
+ rml:inputValueMap [
+ rml:constant "[a filled in title]"
+ ]
+ ]
+ ] ;
+ ] .
+# Any custom function can be used,
+# or nested functions (eg AND/OR),
+# depending on what the engines support
+
+