Versa is a specialized language for addressing and querying an RDF model. It allows traversal of arcs, processing of node contents, and general expression evaluation.
Versa is a specialized language for addressing and querying nodes and arcs in a Resource Description Framework (RDF) model. It uses a simple and expressive syntax, designed to be incorporated into other expression systems, including XML, where, for instance, Versa can be used in extension functions or attributes of extension elements that provide RDF-related capabilities. Versa operates on the abstract graph model of RDF, and not any particular serialization.
Where used in this document, the keywords "SHOULD", "MUST", and "MUST NOT" are to be interpreted as described in RFC 2119 [RFC2119]. However, for readability, these words do not appear in all uppercase letters in this specification.
Versa uses constructs from XML namespaces for convenient abbreviation of URIs. Within this document, in examples and other discussion, some prefixes are commonly used without being defined each time. In this document consider these prefixes to be bound to the following namespaces:
This is just a convenience for this document. There is no normative binding of these prefixes.
Versa queries operate on an RDF model. Any RDF model that follows the RDF Model defined in RDF 1.0 [RDF] is a valid processing space for Versa. There are some cases where the precise behavior of Versa is dependent on implementation details of the RDF model. These cases are noted in this document.
Versa operates on the abstract graph model of RDF. As such it operates on nodes, literals and arcs. Versa does not require that the abstract RDF graph support any of the entailments defined in the RDF semantics [SEMANTIC] specication even though this specification may reference terminology from that specification. For processing of Versa Queries, an implementation is required to support the following set of data types and result types.
Data types are used internally in processing of a versa expression, as opposed to result types which are used to return a result from a completed versa query. The following are the set of data types that must be supported by a versa implementation.
A resource is a reference to a node or a literal in the data model. The actual form of the reference is left to the implementation, however, these can be thought of as the blank nodes allocated to the node or literal based on Simple entailment [SEMANTICS].
A node is reference to a named or unnamed node in the model.
A literal is reference to a literal in the model.
A statement represents an arc in the model.
A heterogeneous ordered collection of any data type (including other lists or sets). Duplicates are allowed.
A heterogeneous unordered collection of any data type (including other sets or lists), with no duplicate values. See the section on equality for a definition of how members of a set are computed to be equal.
It should be noted that rarely is processing of a versa query done on a single resource. In almost all cases, processing is performed on a Set or a List. This specification will explicitly state when this is not the case.
As opposed to data types which are used for internal processing of a versa query, result types are meant to give a meaningful result to a query. The set of result types include all of the data types, as well as those defined below. Please see the Conversions section for the set of rules the govern the conversion of data types to result types.
As a note, results types are not purely limited to the results of a top level versa query. In some cases, data types may be converted to result types while processing. An example of this is the function concat which will convert its sub-expression to string result types before concatenating the strings.
A sequence of zero or more characters, as defined in the XML 1.0 recommendation. Versa strings are similar to XPath strings.
Versa numbers are the same as XPath numbers: positive or negative floating-point numbers, based on the rules and semantics for double precision, 64-bit numbers in IEEE 754.
Boolean types represent logical truth or falsehood. As such there are two boolean literals: true and false.
In some cases it is not possible to convert from one data type to another. In this case, the conversion produces a null output. This psuedo datatype is used as follows:
When implicit conversions between data types and result types are needed, the following matrix defines the operations applied.
| From/To | Resource | Node | Literal | Statement | String | Number | Boolean |
| Resource | Identity | If the resource is a node, then Identity, else null. | If the resource is a literal, then Identity, else null. | See 1. | See 1. | See 1. | See 1. |
| Node | Identity | Identity | null. | See 4. | IF the node is named, the URI of the node, else the empty string. | null | null |
| Literal | Identity | null. | Identity | null. | A string representation of the literal as defined by the grammar including language and datatype if present. | See 2. | null |
| Statement | See 1. | See 5. | null | Identity | null | null | null |
| String | See 1. | If the string represents a URI in the model, then that node, else null. | If the string represents a Literal in the model, then that literal, else null. | null. | Identity | The number that is represented by the string, or NaN. | false if the string is empty, otherwise true. |
| Number | See 1. | null. | if the number is a decimal number, the the literal of the form "number"^^xsd:float, else the literal of the form "number"^^xsd:int. | null. | String representation of the number | Identity | false if the number is positive or negative 0, otherwise true. |
| Boolean | See 1. | null | Conversion to a literal in the form of "boolean"^^xsd:boolean. | null. | "true" or "false" | 0 if false, or 1 if true | Identity |
1 When converting to or from a resource, if the resource is a node, then the node conversion rules are used, else, the literal conversion rules are used.
2 This conversion is left to the underlying data model. If the model supports D-entailment [SEMANTICS] then it may convert the literal to a number based on data type information. If the conversion cannot be made, or the model does not support D-entailment, then the value of the literal is used with the string conversion to number.
4 There is a lot of contreversy regarding statements and reification. This specification ignores that contreversy. If the underlying model chooses to support reification then it may convert a statement to a node that represents that reified statement. If not, then the conversions are all null
When any datatype is converted to a list or set, the results is a list or set of length one with that value as the only member.
When a list is converted to another data type (besides set) the first item in the list is converted to that data type. If the list is empty, the results are null. When a list is converted to a set it produces a set with the same entries as the list, except that if there are duplicate values, any equivalent values following the first are omitted (e.g. set(list(1,2,1)) = set(1,2))
When a set is converted to any data type it is first converted to a list, then the list conversions are applied. As sets are unordered it is not gaurenteed that two subsequent conversions to list will produce the same results. As an example, the following may not always be true string(list(1,2)) = string(list(1,2))
Comparisons between values follow specific rules for each data type. In general if two values are being compared, A and B, B is first converted to the same type as A before the comparison is made.
Comparisons can be explicitly applied in various operations, or can be explicitly made by invoking the relational functions (see below).
Comparisions are defined by three primary comparison operations. More complex comparisons are defined by a boolean combination of these primary comparisons. As an example, the comparison of <= is the results of < or =
The following are the comparison rules for the various types. Note, for comparison of resources, the super type of the resource (node or literal) is computed, then thos comparison rules are followed.
| Data type | < | = | > |
| Node | The node is converted to a string for comparison. | The results are true if the nodes represent the same node in the underlying model. | The node is converted to a string for comparison. |
| Literal | See 1. | See 1. | See 1. |
| Statement | The statement is converted to a node for comparison. | The statement is converted to a node for comparison. | The statement is converted to a node for comparison. |
| Strings | The strings are compared as are XPath strings. | The strings are compared as are XPath strings. | The strings are compared as are XPath strings. |
| Numbers | The numbers are compared as are XPath numbers | The numbers are compared as are XPath numbers | The numbers are compared as are XPath numbers |
| Booleans | The result of converting to a number and comparing. | The result of converting to a number and comparing. | The result of converting to a number and comparing. |
| Lists | Unspecified | True if the lists are of the same length, and each member is equal and in the same order. | Unspecified |
| Sets | Unspecified | True if the sets are of the same length, and each member is equal regardless of order. | Unspecified |
1 Literal comparisons are left to the underlying datamodel and depend on the level of entailment supported by the data model. A model that supports D-entailment [SEMANTICS] may find the following literals equals "01"^^xsd:int and "1e0"^^xsd:int though it is not required by this specification. A minimal implamantation must use the string comparision rules on the value of the literal and would find the previous literals not equal.
Versa defines queries. A query is a combination of literals, traversals and filters, variable references and function calls. Traversala and filters are expressions that match patterns in the RDF model by selecting sets of starting resources and arc resources, and conditions for selecting end-points from the RDF model.
Versa allows you to specify namespace and variable declarations before each query. These declarations are superceded by any declarations passed to the implementation via other means (see the variable and namespace section).
All queries can be expressed within a scope. The default scope if unspecified is the entire RDF model. If specified, a scope is a query that returns a collection of statements, a subgraph of the RDF model, that was created by a previous query. The subsequent query is then executed using the subgraph as the only set of statements. If the scope query returns any result type besides a collection of statements, then the results of the query is the empty set.
Many Versa constructs are evaluated with regard to a context. The context is a value of any data type, and it can always be referred to explicitloy in an expression using the token "."
Note that there are always a set of variable bindings in effect, and a set of function definitions in scope, but these are not formally considered part of the context, as they are in XPath. Variables and functions are discussed below.
Any expression can be grouped using the grouping symbols '(' and ')'. The results if this expression are the same as the result of the nested expression. Grouping is required to specify precedence of a expression when nested in another expression.
Any expression can be sliced. To perform the slice, the expression is converted to a list, then the slice operator is applied. Below are examples of slice operators:
| expression[1] | The item at index 1 (the second item) in the list |
| expression[-1] | The last item in the list. |
| expression[2:] | A list containing all items after the third item. |
| expression[-2:] | A list containing the last two items. |
| expression[:2] | A list containing the first two items. |
| expression[:-2] | A list containing all but the last two items. |
| expression[1:3] | A list containing the second and third items. |
| expression[-4:-2] | A list containing the second and third to last items. |
Resource queries define the lowest level of query and are the building blocks for more complex queries. All resource queries return a set, and most sets are of size one (see string queries below for the exception).
A node query is a query to retrieve a specific node from the scope. If the node specified exists in the scope, then the results of the query are the set containing that node. If the node does not exist in the scope, then the results are an empty set.
There are two different forms of resource query, the first is an absolute URI queryand is specified using the "<" and ">" tokens surronding the URI. In addition, an implementation may support the deprecated uri query of the form @"URI".
The second form of resource query is using a qname. The prefix of the qname is resolved using the set of in scope namespaces mappings (see the section below on variables and namespaces) and converted to a absolute URI query. If the specified prefix is not defined then the results of the query are the empty set.
The following are examples of node queries:
| <http://rdfinference.org> | The node with URI http://rdfinference.org |
| @"http://rdfinference.org" | Same as above but with the optional old uri ref syntax. |
| spam:eggs | if the prefix spam is mapped to the URI http://python.org/, the node with the the URI http://python.org/eggs. |
| myobj:oute66 | if the prefix myobj is mapped to the URI urn:oid:this.is.not.really.a.valid.oid.r, the node with the URI urn:oid:this.is.not.really.a.valid.oid.route66. |
Note that the lexical rules of XML QNames may limit the situations in they may be used in Versa. For instance, if the URIs are UUIDs in URN form. The full form can always be used to express any valid URI.
Absolute URIs support the escaping of unicode characters. See the section on string escaping for more details.
Similar to node queries, literal queries return a list of zero or more literals from the scope. If the specified literal is not in the scope then the results are an empty set. A literal query allows you to specify a string value and an optinal language or datatype to match against.
As a shortcut, queries for boolean and number values can use the simplified syntax. The processor will convert the short-cut value into an appropriate literal (by the conversion rules) and use that for the query.
When used are arguments to function calls, literals are interpreted as literal values, not as queries. If you would like to pass the results of a literal query to a function, see the query method.
Below are some examples of literal queries.
| "foo" | All literals with the value of "foo" regardless of language or datatype. |
| "foo"@en_US | The literal with the value of "foo" in the language of en_US. |
| "foo"@* | All literals with the value of "foo" in any language (but it must have a language). |
| "foo"@!* | The literal with the value of "foo" without any language. |
| "foo"^^xsd:string | The literal with the value of "foo" in the datatype xsd:string. |
| "foo"^^* | All literals with the value of "foo" with any data type (but it must have a datatype). |
| "foo"@!* | The literal with the value of "foo" without any datatype. |
| 'foo' | Same as first query, apostrophe can be used interchangable with quotes. |
| """ foo ' and " allowed """ | A literal query that does not require escaping. |
| 10 | translated into the query "10"^^xsd:int. |
| 10.0 | translated into the query "10.0"^^xsd:float. |
| true | translated into the query "true"^^xsd:boolean. |
Strings support the following escape characters to allow embedding of various content within the strings.
| "\\" | becomes | '\' |
| "\"" | becomes | '"' |
| "\'" | becomes | '\'' |
| "\n" | becomes | '\n' |
| "\r" | becomes | '\r' |
| "\t" | becomes | '\t' |
| "\uXXYY" | becomes | unicode character XXYY |
| "\xXX" | becomes | character XX |
Traversal and filter expressions are the core of Versa. They provide a system for matching patterns in an RDF model by specifying desired nodes and arcs in the graph representing the model. The traversal and filter operators are the bases of the respective expression, and result in a list.
Note: <uri1> - <uri2> -> <uri3> is equiv. to set(ground(<uri1>)) - set(ground(<uri2>)) -> member(set(ground(<uri3>)),.)
The forward traversal operator matches patterns based on given sets of subjects and predicates. It returns a list of resulting objects. It takes the following form:
set-expression - set-expression -> filter-expression
The forward filter operator matches patterns based on given sets of subjects and predicates. In contrast to the forward traversal operator, it returns a list of the subjects that result from the patterns rather than the objects. It takes the following form:
set-expression |- set-expression -> filter-expression
In both cases the first set-expression is a evaluated to obtain list (cast if need be) which are the subjects of statements. Each of these resources is set as the context for evaluating the second set-expression, which is treated as a list of predicates(cast if need be). All statements in the model with these subjects and predicates are marked as candidate statements. The object of each of the candidate statements is evaluated as the context of the filter-expression.
In the case of forward traversal, if the result, after conversion to boolean type, of evaluating the filter-expression is true, the object is added to the list of results. In the case of forward filtering, if the result, after conversion to boolean type, of evaluating the filter-expression is true, the subject of the corresponding statement is added to the list of results.
Unless an ordering aggregate function (see below) is used, the order of the resulting elements in the list is undefined in Versa, and is determined by the underlying model.
The backward traversal operator is similar to the forward traversal operator, but it is used to match patterns using the inverses of predicates. A backward traversal expression takes the following form:
filter-expression <- set-expresion - set-expression
The backward filter operator is similar to the forward filter operator, but it is used to match patterns using the inverses of predicates. A backward filter expression takes the following form:
filter-expression <- set-expression -| set-expression
In both cases, the first set is a set of resources which are the objects of statements, the predicates of which are given by the resources in the second set expression. In the case of traversal, the results are a list of matching statements, and the subject of each statement is evaluated as the context of the boolean expression. If the result, after conversion to boolean type, is true, the subject is added to the list of results. Conversions are automatically applied, as with forward traversal expressions. In the case of filter, the results are the objects of the original statements.
Versa provides a set of special functions which are designed to be used within traversal operations to transform partial results within the context of the traversal.
sortq(set, expression [, vsort:number | vsort:string [, vsort:ascending | vsort:descending ] ])
Editor's note: How to express multi-key sorting?
Editor's note: Are there any others that cannot be expressed as operations on the result list? Grouping primitives, perhaps.
Existential expressions are away to all optimizers signal that ahe source expression is over the set of all resources in the model. In all four cases, the expression could be rewritten by addind all() as the missing expression. So the exitensial expression
[ - rdf:type -> rdfs:Class ]
is evaluated as
all() - rdf:type -> rdfs:Class
Both variables and namespaces can be defined in two seperate manners. The first is through the use of declarations in the versa query. The second is left to the implementation, but a conforming implementation must allow for defining variables and namespaces in some manner external to the query.
In the case where a variable or namespace definition clashes between that defined in the declarations and one expressed externally, then external value is used.
It is an error to attempt to overdie a system defined prefix.
The EBNF for the versa language is available here
/*
* DO NOT EDIT THIS FILE!
*
* Parser generated by BisonGen on Mon Oct 3 16:21:24 2005.
*/
[0] query ::= arc-expression
| resource-expression
| constant-expression
| function-call
| variable-reference
| wrapped-query
| sliced-query
| list-constant
[1] string ::= DOUBLE_QUOTES string_chars DOUBLE_QUOTES
| DOUBLE_QUOTES DOUBLE_QUOTES
[2] string_chars ::= CHARACTER_PLUS
| escape_chars
| string_chars CHARACTER_PLUS
| string_chars escape_chars
[3] escape_chars ::= STRING_ESCAPE
| unicode_escape
[4] unicode_escape ::= UNICODE_ESCAPE
[5] uriref ::= LT absoluteURI GT
| LT GT
[6] absoluteURI ::= CHARACTER_PLUS
| unicode_escape
| CHARACTER_PLUS absoluteURI
| unicode_escape absoluteURI
[7] lang-string ::= string AT LANGUAGE
[8] datatype-string ::= string DOUBLE_CARROT uriref-qname
[9] wrapped-query ::= LEFT_PAREN query RIGHT_PAREN
[10] sliced-query ::= resource-expression slice-operator
| function-call slice-operator
| variable-reference slice-operator
| wrapped-query slice-operator
| sliced-query slice-operator
[11] arc-expression ::= forward-arc-expression
| backward-arc-expression
[12] resource-expression ::= node-expression
| literal-expression
[13] node-expression ::= uriref-pattern
| qname-pattern
| qname-constant-pattern
[14] literal-expression ::= literal-pattern
| typed-literal-pattern
| language-literal-pattern
[15] constant-expression ::= string-constant
| boolean-constant
| number-constant
[16] forward-arc-expression ::= forward-start-expression forward-operator arc-predicate-expression FORWARD_ARROW arc-end-expression
[17] forward-operator ::= PIPE_DASH
| DASH
[18] backward-arc-expression ::= arc-end-expression BACKWARD_ARROW arc-predicate-expression backward-operator backward-start-expression
[19] backward-operator ::= DASH_PIPE
| DASH
[20] function-reference ::= AMPERSAND function-name
[21] argument-expression ::= query
| dot-expression
| function-reference
| anonymous-function
| wild-card
[22] dot-expression ::= DOT
[23] function-call ::= function-name LEFT_PAREN argument-list RIGHT_PAREN
[24] argument-list ::=
| fixed-argument-list
| keyword-argument-list
| fixed-argument-list COMMA keyword-argument-list
[25] fixed-argument-list ::= argument-expression
| fixed-argument-list COMMA argument-expression
[26] keyword-argument-list ::= keyword-argument
| keyword-argument COMMA keyword-argument-list
[27] keyword-argument ::= argument-name EQUALS argument-expression
[28] anonymous-function ::= ANONYMOUS_FUNCTION_START function-argument-definition-list COLON argument-expression RIGHT_PAREN
[29] function-argument-definition-list ::=
| function-fixed-argument-definition-list
| keyword-argument-definition-list
| function-fixed-argument-definition-list COMMA keyword-argument-definition-list
[30] keyword-argument-definition-list ::= keyword-argument
| keyword-argument COMMA keyword-argument-definition-list
[31] variable-name ::= qname
[32] function-name ::= qname
[33] function-fixed-argument-definition-list ::= argument-name
| function-fixed-argument-definition-list COMMA argument-name
[34] argument-name ::= qname
[35] qname ::= NCNAME
| QNAME
[36] arc-start-expression ::= function-call
| anonymous-function
| resource-expression
| variable-reference
| wild-card
| wrapped-query
| list-constant
[37] forward-start-expression ::= arc-start-expression
| forward-arc-expression
[38] backward-start-expression ::= arc-start-expression
| backward-arc-expression
[39] arc-predicate-expression ::= function-call
| anonymous-function
| node-expression
| wild-card
| variable-reference
| wrapped-query
| list-constant
[40] arc-end-expression ::= function-call
| anonymous-function
| resource-expression
| wild-card
| variable-reference
| wrapped-query
| list-constant
| constant-expression
[41] slice-operator ::= LEFT_SQUARE SIMPLE_NUMBER RIGHT_SQUARE
| LEFT_SQUARE SIMPLE_NUMBER COLON RIGHT_SQUARE
| LEFT_SQUARE COLON SIMPLE_NUMBER RIGHT_SQUARE
| LEFT_SQUARE SIMPLE_NUMBER COLON SIMPLE_NUMBER RIGHT_SQUARE
[42] variable-reference ::= DOLLAR variable-name
[43] wild-card ::= WILD_CARD
[44] string-constant ::= string
[45] uriref-pattern ::= uriref
[46] qname-constant-pattern ::= qname
[47] qname-pattern ::= WILD_CARD_COLON NCNAME
| NCNAME COLON_WILD_CARD
[48] literal-pattern ::= lang-string
| datatype-string
[49] list-constant ::= LEFT_SQUARE RIGHT_SQUARE
| LEFT_SQUARE query-list RIGHT_SQUARE
[50] query-list ::= argument-expression
| query-list COMMA argument-expression
[51] typed-literal-pattern ::= string DOUBLE_CARROT typed-literal-pattern-string-type
| WILD_CARD DOUBLE_CARROT typed-literal-pattern-wild-type
[52] typed-literal-pattern-string-type ::= qname-pattern
| BANG qname-pattern
| WILD_CARD
| BANG WILD_CARD
[53] typed-literal-pattern-wild-type ::= uriref
| BANG uriref
| qname
| BANG qname
[54] language-literal-pattern ::= string AT WILD_CARD
| string AT BANG WILD_CARD
| WILD_CARD AT LANGUAGE
| WILD_CARD AT BANG LANGUAGE
[55] number-constant ::= SIMPLE_NUMBER
| COMPLEX_NUMBER
[56] boolean-constant ::= TRUE
| FALSE
[57] uriref-qname ::= uriref
| qname
[58] LT ::= '<'
[59] DOUBLE_QUOTES ::= '\x22'
[60] DOUBLE_QUOTES ::= '\x22\x22\x22'
[61] EQUALS ::= '='
[62] LEFT_PAREN ::= '\('
[63] RIGHT_PAREN ::= '\)'
[64] ANONYMOUS_FUNCTION_START ::= '\(\!'
[65] LEFT_SQUARE ::= '\['
[66] RIGHT_SQUARE ::= '\]'
[67] DOLLAR ::= '\$'
[68] DOT ::= '\.'
[69] COLON ::= '\:'
[70] FORWARD_ARROW ::= '->'
[71] BACKWARD_ARROW ::= '\<-'
[72] DASH ::= '-'
[73] PIPE_DASH ::= '\|{ws}*\-'
[74] DASH_PIPE ::= '\-{ws}*\|'
[75] COMMA ::= ','
[76] BANG ::= '!'
[77] TRUE ::= 'true'
[78] FALSE ::= 'false'
[79] WILD_CARD ::= '\*'
[80] COLON_WILD_CARD ::= '\:\*'
[81] AMPERSAND ::= '&'
[82] WILD_CARD_COLON ::= '\*\:'
[83] DOUBLE_CARROT ::= '\^\^'
[84] QNAME ::= '{NCName}?:{NCName}'
[85] NCNAME ::= '{NCName}'
[86] SIMPLE_NUMBER ::= '[+-]?{Digit}+'
[87] COMPLEX_NUMBER ::= '[+-]?{Digit}+(\.{Digit}*)?([eE][+-]?{Digit}+)'
[88] COMPLEX_NUMBER ::= '[+-]?{Digit}+\.{Digit}*'
[89] DOUBLE_QUOTES ::= '\x27'
[90] AT ::= '\@'
Versa defines a core function library. Extension functions can be defined using a similar mechanism to that provided by XPath.
Conversion functions are special functions that convert their arguments to a particular data type, using the conversion rules described above.
node(expression)
Create a resource. The expression is converted into a string, and that string is used to as a URI to query the model.
number(expression,[,datatype])
If a single argument is passed, then convert the expression to a number as defined above. If to arguments are passed, then the expression if converted to a string, and the underlying model is asked to convert this to a number based on the data type. If the underlying model does not support this then the conversion is completed assuming the datatype argument was not passed.
Set and list functions that return sets and lists.
all()
Returns a set of all resources in the model. This method should be used with care. For a subset of resources, use a pattern. In a traversal or filter use the wild card pattern instead.
distribute(list,
query,
[query, [...]])
distribute converts the first argument into a list. The second and subsequent arguments (the query arguments) are anonymous functions or function references. It uses each item in the list as the sole argument for evaluating each of the query arguments. The result is a list of lists; each entry in the outer list is a list containing the results from evaluating each of the query arguments in order using the Nth list item as context.
For example, the query:
distribute(["a", "ab"], &string-length, (! x : concat("c-", $x)))
returns
[[1, "c-a"], [2, "c-ab"]]
The outer list is of length two because there are two items in the first argument. Each inner list has two items because there are that many query arguments.
map(function-reference, list1, [listn, [...]])
The first argument to map is a function-reference or an anonymous function which will be evaulated with an argument set computed from the context set. To compute the argument set, the ith item is taken from each list. These then form the arguments, in the order of the list epxressions, that are given to the function reference. The processes will be performed as many times as the length of the longst list. Shorter lists will be padded with "null" value.
The result are a list of values, as long as the longest item in the list from the list expression arguments.
As an example, the query:
map(&concat, ["A", "B", "C"], ["1", "2"])
Is equivilent to
[concat("A","2"), concat("B", "2"), concat("C",null)]
and will return a list of length 3:
["A1", "B2", "C"]
And the query:
map((! x : $x-h:formatted-name->*), h:principia-h:author->*)
Returns the formatted name of the author of the book identified as "h:principia", and thus in our sample model would return
["Isaac Newton"]
This is equivalent to the chained traversal expression
h:principia - h:author -> * - h:formatted-name -> *
filter(list, query, [query, [...]])
filter converts the first argument into a list (the source list). The second and following arguments are either function referenceas or anonymous functions. Each query is called once per item in the list with that item as the only argument. If the all queries return true, then the list item is added to the result set.
sort(list, conversion=&string, direction=$versa:ascendind )
The first argument is converted to a list or a set. The result is the list obtained by sorting according to the given criteria. The second parameter indicates the conversion function that should be applied to each item before sorting. It must be a function reference or a anonymous function.
The default is the string conversion function. The third parameter indicates the direction of sorting. The system variables versa:ascending and versa:descending are used to determine the direction. The default is ascending.
union(set, set)
Both arguments are converted to sets, and the result is a set consisting of all items that are in either argument set.
intersection(set, set)
Both arguments are converted to sets, and the result is a set consisting of all items that are in both argument sets.
difference(set, set)
Both arguments are converted to sets, and the result is a set consisting of items that are in he first set but not in the second (set difference).
join(list[, list, [...]])
Each argument is converted to a list, and the result is a list which consists of the concatenation of all the argument lists in order.
statements(subject,predicate,object,result-type = $versa:object-result)
The statements function is the functional equivilant of the traversa and filter operators with the caveats listed below. Each of the first three arguments is interpreted as follows (based on its type).
similar to the operators, the statements function allows the dot expression, and the traversal variables available as arguments. It should be noted though that since function arguments are evaulated at in the containing scope of the function, these need to be wrapped in anonymous functions to have the identical meaning of the operators. As an example, the following are equivilent:
all() - eq($versa:subject,"http://foo.com") -> lt(.,13)
and
statements(all(), (! : eq($versa:subject,"http://foo.com")), (! x : lt($x,13)))
It is an error to pass a function reference, or anonymous function, that requires more then 1 parameter. If the reference takes zero parameters, then it is called without params. If the reference takes a single argument, then it is passed dot.
Number Functions are functions that return number types
add(number,number [,number2 ... ])
Converts all arguments into numbers and returns the result of adding all of the together.
sub(number ,number)
Converts all arguments into numbers and returns the result of subtracting the two..
mul(number,number [,number2 ... ])
Converts all arguments into numbers and returns the result of multiplying all of the together.
div(number ,number)
Converts all arguments into numbers and returns the result of dividing the two..
sum(list )
Converts the argument into a list, then returns the results of converting each argument to a number and adding them all together.
floor(number )
Returns the largest (closest to positive infinity) number that is not greater than the argument and that is an integer..
ceiling(number )
Returns the smallest (closest to negative infinity) number that is not less than the argument and that is an integer..
round(number )
Returns the number that is closest to the argument and that is an integer. If there are two such numbers, then the one that is closest to positive infinity is returned. If the argument is NaN, then NaN is returned. If the argument is positive infinity, then positive infinity is returned. If the argument is negative infinity, then negative infinity is returned. If the argument is positive zero, then positive zero is returned. If the argument is negative zero, then negative zero is returned. If the argument is less than zero, but greater than or equal to -0.5, then negative zero is returned.
length(list)
Converts the argument to a list and returns the number of items in the list. If the argument cannot be converted to a list, then null is returned.
string-length(string)
The number of characters in the string is returned. If the argument cannot be conterted into a string, then null is returned.
find-regex(string , regex,versa:ignore-case = false)
The regex string is interpreted as a POSIX Simple Regular Expression [PSRE] and the return value is the first index at which it is matched in the string. If the versa:ignore-case flag is evaulates to a boolean true, then the regular expression is matched without regard to the case of alphabetic characters. If there is no regular expression match at all, the return value is -1. If the first argument cannot be converted to a string, or the second cannot be converted to a string then null is returned. It is a runtime error if the regex is invalid.
String functions work with strings.
concat(string, string2, [...]])
Each argument is converted to a string, and the result is a string which consists of the concatenation of all the arguments in order.
substring-before(string , string)
Convert all arguments to strings. Return the substring of the first argument that precedes the first occurrence of the second argument, or the empty string if the first argument does not contain the second.
substring-after(string, string)
Convert all arguments to strings. Return the substring of the first argument that succeeds the first occurrence of the second argument, or the empty string if the first argument does not contain the second.
Literal functions work with literals.
canonical(literal)
Convert the literal into a string that is the canonical form of the literal. This assumes that the underlying model support data types and that the literal is datatypes. If not, then the string value of the literal is returned, or null if the argument is not a literal.
language(literal)
Return the language of the literal. If the literal is typed the results are null. If the parameter is not a literal, the results are null. If the argument is a literal without a language, the results are the emty string.
datatype(literal)
Return the datatype of the literal. If the literal is not typed or the argument is not a literal, then the null value is returned.
ground(constant)
Map the constant value into a resource in the datamodel. If the constant represents a URI, then return the node for this URI. If the resource is a literal, then return the literal for the constant. All other parameters result in null.
Boolean Functions are functions that work with booleans. All return boolean types
and(boolean[, boolean, [...]])
Return true if the boolean values of all the arguments are true.
or(boolean[, boolean, [...]])
Return true if the boolean value of one or more arguments are true
not(boolean)
If the boolean value of the argument is true, return false, otherwise return true.
lt(number , number )
Return true if the first is less than the second (after both have been converted to numbers). Otherwise return false.
gt(number , number)
Return true if the first is greater than the second (after both have been converted to numbers). Otherwise return false.
lte(number [ , number ])
Return true if the first is less than or equal the second (after both have been converted to numbers). Otherwise return false.
gte(number , number )
Return true if the first is greater than or equals the second (after both have been converted to numbers). Otherwise return false.
eq(expression , expression )
Return true if the first expression is equal the second expression.
neq(expression , expression)
Return true if the first expression is not equal the second expression.
starts-with(string , string)
Return true if the string value of the first argument starts with the value of the second.
contains(string , string, ignore-case = false)
Return true if the string value of the second argument is a substring value of the first.
[PSRE]: The Open Group UNIX Specification on Regular Expressions
[RFC2119]: RFC 2119 - Key words for use in RFCs to Indicate Requirement Levels
[RDF CONCEPTS]: Resource Description Framework (RDF): Concepts and Abstract Syntax
[RDF]: Resource Description Framework (RDF)
[RDFS]: RDF Vocabulary Description Language 1.0: RDF Schema
[RDF SEMANTICS]: Resource Description Framework (RDF) Semantics
[Editor's note: Yes, this section is in woeful need of work.]
In order to guide the development of Versa some use cases for RDF query have been developed. This section presents these use cases, as well as how they can be addressed using the current specification of Versa
Often one wants to simply check a model for all resources with a given RDF type
A DAML-aware Versa implementation will allow easy querying of explicitly transitive properties, but often one needs to interpret properties tarnsitively without help from the schema.
All of the versa queries work on any RDF model regardless of its interpretation [RDF SEMANTICS]. Mostly, interpretations just effect the amounts of data returned from a Versa query. As an example, a query to get all of the rdf:type properties of an object may return an empty set in a simple interpretation of the model. However, in a RDFS interpretation of the model that supports the entailment rule rdfs4, the query may return the type rdfs:Resource for the query if the resource has been used as a subject or object in a statement.