From cddd45326989e36295e53c5513e2dde94ca4a571 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Wed, 24 Apr 2024 13:19:34 +0200 Subject: [PATCH 01/28] Bundle TREE spec again into spec.bs - without imports --- .../4-provenance-and-summaries.md | 0 spec.bs | 476 +++++++++++++++++- specs/0-introduction.md | 112 ----- specs/1-discovery.md | 59 --- specs/2-traversing.md | 76 --- specs/3-search.md | 83 --- specs/5-imports.md | 18 - specs/6-compatibility.md | 117 ----- 8 files changed, 470 insertions(+), 471 deletions(-) rename {specs => drafts}/4-provenance-and-summaries.md (100%) delete mode 100644 specs/0-introduction.md delete mode 100644 specs/1-discovery.md delete mode 100644 specs/2-traversing.md delete mode 100644 specs/3-search.md delete mode 100644 specs/5-imports.md delete mode 100644 specs/6-compatibility.md diff --git a/specs/4-provenance-and-summaries.md b/drafts/4-provenance-and-summaries.md similarity index 100% rename from specs/4-provenance-and-summaries.md rename to drafts/4-provenance-and-summaries.md diff --git a/spec.bs b/spec.bs index fa88f77..d930d94 100644 --- a/spec.bs +++ b/spec.bs @@ -17,11 +17,475 @@ Abstract: This way, a user agent that can interpret the TREE hypermedia controls can find the most efficient way to the members of interest to them. -
path: specs/0-introduction.md
-
path: specs/1-discovery.md
-
path: specs/2-traversing.md
-
path: specs/3-search.md
-
path: specs/5-imports.md
-
path: specs/6-compatibility.md
+# Overview # {#overview} + +An overview of the TREE specification with the TREE collection, a reference to the first focus node of its members, and the relations to other nodes from the current node. + +The TREE specification introduces these core concepts: + * a tree:Collection is a subclass of dcat:Dataset ([[!vocab-dcat-3]]). The specialization being that it is a DCAT dataset a collection of members. It typically has these properties when described in a node: + - tree:member points at the first focus node from which to retrieve and extract all quads of a member. + - tree:view points to the current tree:Node you’re visiting. + - tree:shape indicates the [[!SHACL]] shape to which each member in the collection adheres. + - tree:viewDescription links to a description of the view (a tree:ViewDescription). Multiple descriptions MAY be provided that MUST be combined. + * a tree:Node: is a page on which relations to other pages are described through the tree:relation predicate, and/or through which a next tree:Node can be found by using the tree:search form. + * a tree:Relation is a relation from one node to another. An extension of this class indicates a specific type of relation (e.g., a tree:GreaterThanRelation). A relation typically has these properties: + - a tree:node the URL of the other node + - a tree:path indicating to which of the members' properties this relation applies + - a tree:value indicating a value constraint on the members' values + - a tree:remainingItems defining how many members can be reached when following this relation + * a tree:ViewDescription is a subclass of dcat:DataService and serves a tree:Collection. + - a tree:search describes a search form that allows an agent to jump to a specific tree:Node. + +The first step when creating a TREE hypermedia interface is defining a collection of members: + +
+ ```turtle + ex:Collection1 a tree:Collection; + rdfs:label "A Collection of subjects"@en; + tree:member ex:Subject1, ex:Subject2 . + + ex:Subject1 a ex:Subject ; + rdfs:label "Subject 1" ; + ex:value 1 . + + ex:Subject2 a ex:Subject ; + rdfs:label "Subject 2" ; + ex:value 2 . + ``` +
+ +From the moment this collection of members grows too large for one page, a fragmentation needs to be created in which an initial set of member can be found on an entry node, and more members can be found by interpreting the TREE hypermedia controls. This is illustrated by the next example: + +
+ ```turtle + > HTTP GET https://example.org/Node1 + + ex:Collection1 a tree:Collection; + tree:view ex:Node1 ; + tree:member ex:Subject1, ex:Subject2 . + + ex:Node1 a tree:Node ; + tree:relation ex:R1,ex:R2 . + + ex:R1 a tree:GreaterThanOrEqualToRelation ; + tree:node ex:Node3 ; # This is the URL of another page + tree:value 3; + tree:path ex:value . + + ex:R1 a tree:LessThanRelation ; # This is very useful for a client that is looking for a value 10 or greater + tree:node ex:Node3 ; # This is the URL of another page + tree:value 10; + tree:remainingItems 7 ; + tree:path ex:value . + + ex:R2 a tree:GreaterThanOrEqualToRelation ; + tree:node ex:Node4 ; # This is the URL of another page + tree:value 10; + tree:remainingItems 10 ; + tree:path ex:value . + + ex:Subject1 a ex:Subject ; + rdfs:label "Subject 1" ; + ex:value 1 . + + ex:Subject2 a ex:Subject ; + rdfs:label "Subject 2" ; + ex:value 2 . + ``` +
+ +
+ Thanks to the [member extraction algorithm](#member-extraction-algorithm), a data publisher can choose to define their members in different ways: + 1. As in the examples above: all quads with the object of the tree:member quads as a subject (and recursively the quads of their blank nodes) are by default included (see also [[!CBD]]), except when they would explicitely not be included in case 3, when the shape would be closed. + 2. Out of band / in band: + - when no quads of a member have been found, the member will be dereferenced. This allows to publish the member on a separate page. + - part of the member can be maintained elsewhere when a shape is defined (see 3) + 3. By defining a more complex shape with tree:shape, also nested entities can be included in the member + 4. By putting the triples in a named graph of the object of tree:member, all these triples will be matched. +
+ +# Definitions # {#formalizations} + +A tree:Collection is a set of tree:Members. The set of members MAY be empty. + +A tree:Member is a set of (at least one) quad(s) defined by the member extraction algorithm (next subsection). + +A tree:Node is a dereferenceable resource containing tree:Relations and a subset of () members of the collection. In a tree:Node, both the set of tree:Relations as the subset of members MAY be empty. The same member MAY be contained in multiple nodes. + +A tree:Relation is a function denoting a conditional link to another tree:Node. + +A tree:Node, apart from the root node, has exactly one other tree:Node linking into it through one or more relations. + +Note: The condition of multiple tree:Relations to the same tree:Node MUST be combined with a logical AND. + +A View is a specific set of interlinked tree:Nodes, that together contain all members in a collection. A specific view will adhere to a certain growth or tree balancing strategy. In one View, completeness MUST be guaranteed, unless the View has a retention policy which becomes possible in LDES. + +A tree:search form is an IRI template, that when filled out with the right parameters becomes a tree:Node IRI, or when dereferenced will redirect to a tree:Node from which all members in the collection that adhere to the described comparator can be found. + +## The member extraction algorithm ## {#member-extraction-algorithm} + +The set of quads the are part of the member, are defined by the [shape templates algorithm](https://w3id.org/tree/specification/shape-templates), provided as a separate report to this specification. +It is a combination of Concise Bounded Descriptions, named graphs and Shape Templates. +The latter uses the sh:NodeShape from the tree:shape property on the collections as an indication of the topology of the member graph. + +Note: The way we process SHACL shapes into Shape Template is important to understand in order to know when an HTTP request will be triggered when designing SHACL shapes. A cardinality constraint not being exactly matched or a sh:pattern not being respected will not trigger an HTTP request, and instead just add the invalid quads to the Member. This is a design choice: we only define triggers for HTTP request from the SHACL shape to come to a complete set of quads describing the member the data publisher pointed at using tree:member. + +# Discovery and source selection# {#hypermedia} + +TREE tackles discovery and source selection on three levels: i) interface discovery, ii) view discovery, and iii) dataset discovery. +Interface discovery discovers what collection the current page is part of, and discovers what the next possible HTTP requests are through relations and search forms. +One dataset can have multiple views that can be published across different servers, selecting one for a certain use case is part of the view discovery. +Dataset discovery is then selecting a tree:Collection of interest. + + +## Interface discovery ## {#interface-discovery} + +Interface discovery starts when a URL is provided to a specific tree:Node. +A node from which all members of a collection can be discovered (an “entry node”), can be found through a triple stating ex:C1 tree:view ex:N1 with ex:C1 being a tree:Collection and ex:N1 being a tree:Node. + +When the current page is a tree:Node, there MUST be a property linking the current page URL to the URI of the tree:Collection. However, not from all tree:Nodes all members can be reached, and therefore 2 other properties can be used: void:subset, or the inverse property, dcterms:isPartOf. + +ex:C1 tree:view <> . links the current page to the tree:Collection. + +We refer to next chapters for traversing across multiple relations, or for using search forms. + +## View discovery ## {#multiple-views} + +Todo: This will be reworked + +Note: How a client picks the right view is use case specific. The tree:ViewDescription’s properties can help in that regards. + +In order to prioritize a specific view link, the relations and search forms in the entry nodes can be studied for their relation types, path or remaining items. +The class tree:ViewDescription indicates a specific TREE structure on a tree:Collection. +Through the property tree:viewDescription a tree:Node can link to an entity that describes the view, and can be reused in data portals as the dcat:DataService. + +
+ ```turtle + ## What can be found in a tree:Node + ex:N1 a tree:Node ; + tree:viewDescription ex:View1 . + + ex:C1 a tree:Collection ; + tree:view ex:N1 . + + ## What can be found on a data portal + ex:C1 a dcat:Dataset . + ex:View1 a tree:ViewDescription, dcat:DataService ; + dcat:endpointURL ex:N1 ; # The entry point that can be advertised in a data portal + dcat:servesDataset ex:C1 . + ``` +
+ +When there is no tree:viewDescription property in this page, a client either already discovered the description of this view in an earlier tree:Node, either the current tree:Node is implicitly the ViewDescription. Therefore, when the property path tree:view → tree:viewDescription does not yield a result, the view properties MUST be extracted from the object of the tree:view triple. +A tree:Node can also be double typed as the tree:ViewDescription. A client must thus check for ViewDescriptions on both the current node without the tree:viewDescription qualification, as on the current node with the tree:viewDescription link. + + +## Dataset discovery ## {#multiple-collections} + +When multiple collections are found by a client, it can choose to prune the collections based on the tree:shape property. +Therefore a data publisher SHOULD annotate a tree:Collection instance with a SHACL shape. +The tree:shape points to a SHACL description of the shape (sh:NodeShape). + +Note: the shape can be a blank node, or a named node on which you should follow your nose when it is defined at a different HTTP URL. + +Note: For compatibility with the [Solid specifications](https://solidproject.org/TR/), a ShEx shape may also be given (see the chapter on compatibility bellow). + +# The tree:Relations # {#relations} + +The initial configuration of the tree:Collection and the description of the view is always provided when the view has been discovered, either in a separate document describing the view, either in the entry node itself. The configuration MUST be reused on any subsequent tree:Node. + +While discovering and traversing the interface, a client MUST take the descriptions on top of the Node, the View and the Collection with it. + +## Traversing relations ## {#traversing} + +A tree:Node element MAY have one or more tree:relation properties. A relation is an entity of the type tree:Relation, and MAY have a more specific type. A tree:Relation MUST have one tree:node object of the type tree:Node. By default, all nodes need to be followed, unless the client is able to select this relation for pruning (see next section). + +The tree:Relation’s tree:value SHOULD be set. The object of tree:value SHOULD be accompanied by a data type when it is a literal value. + +Every tree:Relation SHOULD have a tree:path, indicating the path from the member to the object on which the tree:Relation applies. For the different ways to express or handle a tree:path, we refer to [2.3.1 in the shacl specification](https://www.w3.org/TR/shacl/#x2.3.1-shacl-property-paths). All possible combinations of e.g., shacl:alternativePath, shacl:inversePath or shacl:inLanguage in the SHACL spec can be used. When shacl:alternativePath is used, the order in the list will define the importance of the order when evaluating the tree:Relation. A wildcard in the path is limited to the tree:shape of the tree:Collection. +The result of the evaluation of the tree:path, is the value that must be compared to the tree:value. + +Every tree:Relation MAY provide a tree:remainingItems. A client MAY use tree:remainingItems to estimate the completeness of the downloaded elements to the end-user. + +Note: When traversing, a client SHOULD keep a list of already visited pages, as despite this being the TREE spec, circular references and back-links are not explicitly prohibited. + +A tree:import MAY be defined in the tree:Relation instance. When there is a tree:path defined, and when the relation is flagged interesting to follow, the import link needs to be downloaded in order to find the necessary literals to be compared (it is thus already a tree:ConditionalImport. + +Note: An example of a tree:import is given [in the repository](https://github.com/TREEcg/specification/blob/master/examples/geospatially-ordered-public-transport/first.ttl#L27). + +When dereferencing the object of a tree:node triple, the client MUST follow redirects. The URL to be used as the tree:Node URL is the last URL after redirects. + +Note: This enables rebalancing search trees. + +## Fallbacks ## {#fallbacks} + +When there is no tree:view triple provided, a client MUST use the tree:Collection from the previous page and still continue extracting members, and extract further relations defined on the current page URL. + +When there are no tree:members and/or no tree:Collection defined, then still a tree:Relation can be defined. The tree:path in the tree:Relation then refers to a pattern that can start from every triple in the page. + +When no tree:path is defined, the tree:value MUST be compared to all members’ triples that *can be compared to* the tree:value as defined by the type of the relation (or when no members or collection are defined, on every triple in the page). +When due to rdfs:range incompatibility, the object cannot be compared, the object will not be considered for comparison. + +Note: This may enable server developers to indicate an index on all literals of the members (e.g., a prefix relation on title, description and body text) without having to indicate all of the alternative paths in the tree:path. + +The target object of a tree:path SHOULD be materialized in the current Node document, but when it is not, the object MAY be considered implicit on the condition both tree:path and tree:member are defined. +In contrast to sh:path, a tree:path MAY refer to an implicit property and may not be materialized in the current response. This may break SPARQL processors that did not yet come across the object before in their query plan. However, the tree may still be useful for query processors that, for example, prioritize queries according to the user’s location, and first download nodes that are nearby the user. Therefore, the materialized location of the object is not needed. While not recommended, possible heuristics could try to infer the data, could try to fetch it through another tree:Collection, or retrieve it using URI dereferencing. + +## Specific relations ## {#relationsubclasses} + +When the *only* type given for a certain Relation is tree:Relation, then the client must dereference all of the nodes. While this may seem useless, it can be used for the same use case as a hydra:PartialCollectionView. + +For other types check the chapter on relation types in the vocabulary [](#Relation). + +### Comparing strings ### {#strings} + +String values have three specific type of relations: the tree:PrefixRelation, the tree:SubstringRelation and the tree:SuffixRelation. + +Note: We experimented with server-chosen locales such that ça suffit can also be found when following a tree:PrefixRelation with a tree:value "c" (which at this moment is not supported). That would require an understanding of locales, and [browser/JavaScript support for locales is too low to be useful at this point](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_identification_and_negotiation). + +Also the comparator relations such as tree:GreaterThanRelation can be used. +The strings MUST then be compared according to *case sensitive unicode ordering*. + +When a tree:path is defined, mind that you also may have to check the language of the element using the property shacl:inLanguage +More languages MAY be set. +When no language is set, all strings are compared. + +Note: If you want to have one resource containing both e and é as a prefix, you will have to create multiple relations to the same tree:Node. + +### Comparing named nodes ### {#named-nodes} + +When using comparator relations such as tree:GreaterThanRelation, named nodes must be compared as defined in the [ORDER BY section of the SPARQL specification](https://www.w3.org/TR/sparql11-query/#modOrderBy). + +### Comparing geospatial features ### {#geospatial} + +The tree:GeospatiallyContainsRelation is the relation than can be used to express all further members will be contained within a geospatial region defined by the WKT String in the tree:value. + +When using tree:GeospatiallyContainsRelation, the tree:path MUST refer to a literal containing a WKT string, such as geosparql:asWKT. + +### Comparing time literals ### {#time} + +When using relations such as tree:LessThanRelation or tree:GreaterThanRelation, the time literals need to be compared according to these 3 possible data types: xsd:date, xsd:dateTime or xsd:dateTimeStamp. + + +# Search forms # {#searching} + +Searching through a TREE will allow you to immediately jump to the right tree:Node. +TREE relies on the [Hydra search specification](http://www.hydra-cg.com/spec/latest/core/#hydra:search) for its search forms. +It does however extend Hydra with specific search properties (hydra:IriTemplate) for different types of search forms, and searches starting from a tree:ViewDescription, to which the search form is linked with tree:search. +The behaviour of the search form fully depends on the specific property, for which TREE introduces a couple of specific properties: + +## Geospatial XYZ tiles search form ## {#xyztiles} + +Three properties allow to specify a geospatial XYZ tiles template (also known as slippy maps). + 1. tree:longitudeTile describes the X value + 2. tree:latitudeTile descrbes the Y value + 3. tree:zoom describes the zoom level + +All properties expect positive integers. + +
+ ```turtle + a tree:Collection ; + dcterms:title "A prototype tree:Collection for Linked OpenStreetMap’s roads"@en ; + tree:view . + + a tree:Node ; + tree:viewDescription . + + a tree:ViewDescription ; + tree:search [ + a hydra:IriTemplate ; + hydra:template "https://tiles.openplanner.team/planet/20201103-095900/{z}/{x}/{y}" ; + hydra:variableRepresentation hydra:BasicRepresentation ; + hydra:mapping [ + a hydra:IriTemplateMapping ; + hydra:variable "x"; + hydra:property tree:longitudeTile; + hydra:required true + ],[ + a hydra:IriTemplateMapping ; + hydra:variable "y"; + hydra:property tree:latitudeTile; + hydra:required true + ],[ + a hydra:IriTemplateMapping ; + hydra:variable "z"; + hydra:property tree:zoom; + hydra:required true + ] + ] . + + ``` +
+ +This search form describes a specific search form that uses a quad tree. The zoom level describes the depth, the longitudeTile and latitudeTile describe the x and y index of the fragmentation. (e.g., on zoom level 0, there’s 1 tile, on zoom level 1, there are 4 tiles, etc.). + +## Searching through a list of objects ordered by time ## {#timesearch} + +Same as the previous example but with the predicate tree:timeQuery expecting an xsd:dateTime. +This time however, when the page itself does not exist, a redirect is doing to happen to the page containing the timestamp. +A tree:path can indicate the time predicate which is intended. + +
+ ```turtle + a tree:Collection ; + dcterms:title "An example collection with a time search view"@en ; + tree:view . + + a tree:Node ; + tree:viewDescription . + + a tree:ViewDescription ; + tree:search [ + a hydra:IriTemplate ; + hydra:template "https://example.org/{generatedAt}" ; + hydra:variableRepresentation hydra:BasicRepresentation ; + hydra:mapping [ + a hydra:IriTemplateMapping ; + hydra:variable "generatedAt"; + tree:path prov:generatedAtTime; + hydra:property tree:timeQuery; + hydra:required true + ] + ] . + ``` +
+ +# Imports # {#imports} + +A tree:import can be defined on multiple levels. When defined as part of a tree:Node, this document always needs to be fetched when processing this Node. +When defined as part of the tree:Relation, one MUST fetch the import when the relation needs to be correctly evaluated (e.g., the resulting page contains elements without materialized WKT strings, which however can be fetched from the import). +When importing a file, no hypermedia relations will be followed from that import in order to get more data. + +A tree:importStream can also be defined for providing a pubsub interface for subscribing to real-time updates. The object SHOULD be a [[!websockets]] or Server-Sent Events ([[!eventsource]]). + +Instead of tree:import, one can also use tree:conditionalImport which links to an object of the type tree:ConditionalImport with these properties: + + * tree:import with a link to the page to import, or a tree:importStream with a pubsub stream to import (optionally) + * tree:path with a property path that indicates the resource that elements in the imported resource contain + +Note: imports are powerful to keep recurring objects in a separate, more cacheable, resource. + +No hypermedia controls in the body MUST be interpreted in the imported resource and the object must be fully contained within that information resource. + +On the resources to import, Memento [[!RFC7089]] controls MAY be provided for historic versions. + +# Compatibility # {#compatibility} + +## DCAT ## {#dcat} + +[[!VOCAB-DCAT-2]] is the standard for Open Data Portals by W3C. In order to find TREE compliant datasets in data portals, there SHOULD be a dcat:endpointDescription from the dcat:DataService to the entrypoint where the tree:Collections and the tree:ViewDescriptions are listed. Furthermore, there SHOULD be a dct:conformsTo this URI: https://w3id.org/tree/specification. + +## Hydra ## {#hydra} + +A tree:Collection is compatible with the [Hydra Collections specification](https://www.hydra-cg.com/spec/latest/core/#collections). However, instead of hydra:view, we use tree:view and do not link to a hydra:PartialCollectionView but to a tree:Node. +A hydra:Collection can thus also be extended with a tree:shape and tree:view. +When this is done, also hydra:member can be used instead of tree:member. + +hydra:totalItems can be used to indicate the total amount of elements in the collection. +Hydra paging controls such as hydra:next and hydra:previous are semantically equivalent to a tree:Relation element that only contains a tree:node property. + +## Activity Streams 2.0 ## {#activitystreams} + +A tree:Collection is also compatible with [[!activitystreams-core]]’s specification of [paged collections](https://www.w3.org/TR/activitystreams-core/#collections). +Instead of dcterms:isPartOf, also as:partOf can be used to indicate that the current page is part of the full collection. +While Hydra and TREE link to the members of the collection by using the specific collection as a subject, Activity Streams 2.0 (AS) indicates a member starting from the page URL. +Therefore, when using AS collections, a client implementation should gather the members from the tree:Node or as:CollectionPage instead. + +as:totalItems can be used to indicate the total amount of elements in the collection. + +AS paging controls such as as:nextand as:previous are semantically equivalent to a tree:Relation element that only contains a tree:node property. + +## LDP Containers ## {#ldp} + +In [[!LDP]], the tree:view can be applied on top of the ldp:Container instance. +Members can be found through ldp:contains, and/or through the indirect ldp:membershipResource and ldp:hasMemberRelation or ldp:isMemberOfRelation construct. + +If this container is paged by the [[!ldp-paging]] (chapter 7) spec, then this MUST be ignored. + +If there is an ordering, this MUST be ignored by TREE clients (the relations contain all necessary information for pruning). + +## Shape trees ## {#shapetrees} + +[The Shape Trees specification](https://shapetrees.org/TR/specification/) is specifically built to work within existing ecosystems. +As it was conceived to interoperate with LDP, the term Container in the Shape Trees spec can also be interpreted as a tree:Collection. +Shape Trees can help in the source selection of what specific tree:Collection to pick for your goal, and may add hierarchies to a set of tree:Collections. +A client MAY infer a tree:shape of the collection through the st:validatedBy property of the Shapes Tree. + +An example of a collection using Shape Tree terms. In this example a sensor with some observations is validated by using a [Shape Expressions](http://shex.io/shex-semantics/) (ShEx) file. + +
+ ```turtle + @prefix sosa: . + @prefix om: . + @prefix ldp: . + + <2021.ttl#Collection> a ldp:Container; + st:validatedBy ; + tree:member , . + + + a sosa:Sensor; + sosa:madeObservation + , + ; + sosa:observes om:Temperature . + + + a sosa:Observation; + sosa:observedProperty om:Temperature; + sosa:madeBySensor ; + sosa:hasResult ; + sosa:resultTime "2020-08-25T07:05:31Z"^^xsd:dateTime . + + a om:Measure; + om:hasValue "22"^^xsd:float; + om:hasUnit om:degreeCelsius . + + + a sosa:Observation; + sosa:observedProperty om:Temperature; + sosa:madeBySensor ; + sosa:hasResult ; + sosa:resultTime "2020-08-25T07:05:32Z"^^xsd:dateTime . + + a om:Measure; + om:hasValue "22"^^xsd:float; + om:hasUnit om:degreeCelsius . + + + a sosa:Sensor; + sosa:observes om:Temperature . + ``` + + And its corresponding ShEx file (called Sensor.shex) + + ```shex + PREFIX sosa: + PREFIX xsd: + PREFIX om: + PREFIX rdfs: + + <#Sensor> { + a [sosa:Sensor] ; + sosa:observes [om:Temperature] ; + sosa:madeObservation @<#TemperatureObservation> * + } + + <#TemperatureObservation> { + a [sosa:Observation] ; + sosa:resultTime xsd:dateTime ; + sosa:madeBySensor @<#Sensor> ? ; + sosa:observedProperty [om:Temperature]; + sosa:hasResult @<#TemperatureResult> + } + + <#TemperatureResult> { + a [om:Measure]; + om:hasValue xsd:float ; + om:hasUnit [om:degreeCelsius] + } + ``` +
path: vocabulary.md
diff --git a/specs/0-introduction.md b/specs/0-introduction.md deleted file mode 100644 index 07b2335..0000000 --- a/specs/0-introduction.md +++ /dev/null @@ -1,112 +0,0 @@ -# Overview # {#overview} - -An overview of the TREE specification with the TREE collection, a reference to the first focus node of its members, and the relations to other nodes from the current node. - -The TREE specification introduces these core concepts: - * a tree:Collection is a subclass of dcat:Dataset ([[!vocab-dcat-3]]). The specialization being that it is a DCAT dataset a collection of members. It typically has these properties when described in a node: - - tree:member points at the first focus node from which to retrieve and extract all quads of a member. - - tree:view points to the current tree:Node you’re visiting. - - tree:shape indicates the [[!SHACL]] shape to which each member in the collection adheres. - - tree:viewDescription links to a description of the view (a tree:ViewDescription). Multiple descriptions MAY be provided that MUST be combined. - * a tree:Node: is a page on which relations to other pages are described through the tree:relation predicate, and/or through which a next tree:Node can be found by using the tree:search form. - * a tree:Relation is a relation from one node to another. An extension of this class indicates a specific type of relation (e.g., a tree:GreaterThanRelation). A relation typically has these properties: - - a tree:node the URL of the other node - - a tree:path indicating to which of the members' properties this relation applies - - a tree:value indicating a value constraint on the members' values - - a tree:remainingItems defining how many members can be reached when following this relation - * a tree:ViewDescription is a subclass of dcat:DataService and serves a tree:Collection. - - a tree:search describes a search form that allows an agent to jump to a specific tree:Node. - -The first step when creating a TREE hypermedia interface is defining a collection of members: - -
- ```turtle - ex:Collection1 a tree:Collection; - rdfs:label "A Collection of subjects"@en; - tree:member ex:Subject1, ex:Subject2 . - - ex:Subject1 a ex:Subject ; - rdfs:label "Subject 1" ; - ex:value 1 . - - ex:Subject2 a ex:Subject ; - rdfs:label "Subject 2" ; - ex:value 2 . - ``` -
- -From the moment this collection of members grows too large for one page, a fragmentation needs to be created in which an initial set of member can be found on an entry node, and more members can be found by interpreting the TREE hypermedia controls. This is illustrated by the next example: - -
- ```turtle - > HTTP GET https://example.org/Node1 - - ex:Collection1 a tree:Collection; - tree:view ex:Node1 ; - tree:member ex:Subject1, ex:Subject2 . - - ex:Node1 a tree:Node ; - tree:relation ex:R1,ex:R2 . - - ex:R1 a tree:GreaterThanOrEqualToRelation ; - tree:node ex:Node3 ; # This is the URL of another page - tree:value 3; - tree:path ex:value . - - ex:R1 a tree:LessThanRelation ; # This is very useful for a client that is looking for a value 10 or greater - tree:node ex:Node3 ; # This is the URL of another page - tree:value 10; - tree:remainingItems 7 ; - tree:path ex:value . - - ex:R2 a tree:GreaterThanOrEqualToRelation ; - tree:node ex:Node4 ; # This is the URL of another page - tree:value 10; - tree:remainingItems 10 ; - tree:path ex:value . - - ex:Subject1 a ex:Subject ; - rdfs:label "Subject 1" ; - ex:value 1 . - - ex:Subject2 a ex:Subject ; - rdfs:label "Subject 2" ; - ex:value 2 . - ``` -
- -
- Thanks to the [member extraction algorithm](#member-extraction-algorithm), a data publisher can choose to define their members in different ways: - 1. As in the examples above: all quads with the object of the tree:member quads as a subject (and recursively the quads of their blank nodes) are by default included (see also [[!CBD]]), except when they would explicitely not be included in case 3, when the shape would be closed. - 2. Out of band / in band: - - when no quads of a member have been found, the member will be dereferenced. This allows to publish the member on a separate page. - - part of the member can be maintained elsewhere when a shape is defined (see 3) - 3. By defining a more complex shape with tree:shape, also nested entities can be included in the member - 4. By putting the triples in a named graph of the object of tree:member, all these triples will be matched. -
- -# Definitions # {#formalizations} - -A tree:Collection is a set of tree:Members. The set of members MAY be empty. - -A tree:Member is a set of (at least one) quad(s) defined by the member extraction algorithm (next subsection). - -A tree:Node is a dereferenceable resource containing tree:Relations and a subset of () members of the collection. In a tree:Node, both the set of tree:Relations as the subset of members MAY be empty. The same member MAY be contained in multiple nodes. - -A tree:Relation is a function denoting a conditional link to another tree:Node. - -A tree:Node, apart from the root node, has exactly one other tree:Node linking into it through one or more relations. - -Note: The condition of multiple tree:Relations to the same tree:Node MUST be combined with a logical AND. - -A View is a specific set of interlinked tree:Nodes, that together contain all members in a collection. A specific view will adhere to a certain growth or tree balancing strategy. In one View, completeness MUST be guaranteed, unless the View has a retention policy which becomes possible in LDES. - -A tree:search form is an IRI template, that when filled out with the right parameters becomes a tree:Node IRI, or when dereferenced will redirect to a tree:Node from which all members in the collection that adhere to the described comparator can be found. - -## The member extraction algorithm ## {#member-extraction-algorithm} - -The set of quads the are part of the member, are defined by the [shape templates algorithm](https://w3id.org/tree/specification/shape-templates), provided as a separate report to this specification. -It is a combination of Concise Bounded Descriptions, named graphs and Shape Templates. -The latter uses the sh:NodeShape from the tree:shape property on the collections as an indication of the topology of the member graph. - -Note: The way we process SHACL shapes into Shape Template is important to understand in order to know when an HTTP request will be triggered when designing SHACL shapes. A cardinality constraint not being exactly matched or a sh:pattern not being respected will not trigger an HTTP request, and instead just add the invalid quads to the Member. This is a design choice: we only define triggers for HTTP request from the SHACL shape to come to a complete set of quads describing the member the data publisher pointed at using tree:member. diff --git a/specs/1-discovery.md b/specs/1-discovery.md deleted file mode 100644 index f6bbc05..0000000 --- a/specs/1-discovery.md +++ /dev/null @@ -1,59 +0,0 @@ -# Discovery and source selection# {#hypermedia} - -TREE tackles discovery and source selection on three levels: i) interface discovery, ii) view discovery, and iii) dataset discovery. -Interface discovery discovers what collection the current page is part of, and discovers what the next possible HTTP requests are through relations and search forms. -One dataset can have multiple views that can be published across different servers, selecting one for a certain use case is part of the view discovery. -Dataset discovery is then selecting a tree:Collection of interest. - - -## Interface discovery ## {#interface-discovery} - -Interface discovery starts when a URL is provided to a specific tree:Node. -A node from which all members of a collection can be discovered (an “entry node”), can be found through a triple stating ex:C1 tree:view ex:N1 with ex:C1 being a tree:Collection and ex:N1 being a tree:Node. - -When the current page is a tree:Node, there MUST be a property linking the current page URL to the URI of the tree:Collection. However, not from all tree:Nodes all members can be reached, and therefore 2 other properties can be used: void:subset, or the inverse property, dcterms:isPartOf. - -ex:C1 tree:view <> . links the current page to the tree:Collection. - -We refer to next chapters for traversing across multiple relations, or for using search forms. - -## View discovery ## {#multiple-views} - -Todo: This will be reworked - -Note: How a client picks the right view is use case specific. The tree:ViewDescription’s properties can help in that regards. - -In order to prioritize a specific view link, the relations and search forms in the entry nodes can be studied for their relation types, path or remaining items. -The class tree:ViewDescription indicates a specific TREE structure on a tree:Collection. -Through the property tree:viewDescription a tree:Node can link to an entity that describes the view, and can be reused in data portals as the dcat:DataService. - -
- ```turtle - ## What can be found in a tree:Node - ex:N1 a tree:Node ; - tree:viewDescription ex:View1 . - - ex:C1 a tree:Collection ; - tree:view ex:N1 . - - ## What can be found on a data portal - ex:C1 a dcat:Dataset . - ex:View1 a tree:ViewDescription, dcat:DataService ; - dcat:endpointURL ex:N1 ; # The entry point that can be advertised in a data portal - dcat:servesDataset ex:C1 . - ``` -
- -When there is no tree:viewDescription property in this page, a client either already discovered the description of this view in an earlier tree:Node, either the current tree:Node is implicitly the ViewDescription. Therefore, when the property path tree:view → tree:viewDescription does not yield a result, the view properties MUST be extracted from the object of the tree:view triple. -A tree:Node can also be double typed as the tree:ViewDescription. A client must thus check for ViewDescriptions on both the current node without the tree:viewDescription qualification, as on the current node with the tree:viewDescription link. - - -## Dataset discovery ## {#multiple-collections} - -When multiple collections are found by a client, it can choose to prune the collections based on the tree:shape property. -Therefore a data publisher SHOULD annotate a tree:Collection instance with a SHACL shape. -The tree:shape points to a SHACL description of the shape (sh:NodeShape). - -Note: the shape can be a blank node, or a named node on which you should follow your nose when it is defined at a different HTTP URL. - -Note: For compatibility with the [Solid specifications](https://solidproject.org/TR/), a ShEx shape may also be given (see the chapter on compatibility bellow). diff --git a/specs/2-traversing.md b/specs/2-traversing.md deleted file mode 100644 index 1238e84..0000000 --- a/specs/2-traversing.md +++ /dev/null @@ -1,76 +0,0 @@ -# The tree:Relations # {#relations} - -The initial configuration of the tree:Collection and the description of the view is always provided when the view has been discovered, either in a separate document describing the view, either in the entry node itself. The configuration MUST be reused on any subsequent tree:Node. - -While discovering and traversing the interface, a client MUST take the descriptions on top of the Node, the View and the Collection with it. - -## Traversing relations ## {#traversing} - -A tree:Node element MAY have one or more tree:relation properties. A relation is an entity of the type tree:Relation, and MAY have a more specific type. A tree:Relation MUST have one tree:node object of the type tree:Node. By default, all nodes need to be followed, unless the client is able to select this relation for pruning (see next section). - -The tree:Relation’s tree:value SHOULD be set. The object of tree:value SHOULD be accompanied by a data type when it is a literal value. - -Every tree:Relation SHOULD have a tree:path, indicating the path from the member to the object on which the tree:Relation applies. For the different ways to express or handle a tree:path, we refer to [2.3.1 in the shacl specification](https://www.w3.org/TR/shacl/#x2.3.1-shacl-property-paths). All possible combinations of e.g., shacl:alternativePath, shacl:inversePath or shacl:inLanguage in the SHACL spec can be used. When shacl:alternativePath is used, the order in the list will define the importance of the order when evaluating the tree:Relation. A wildcard in the path is limited to the tree:shape of the tree:Collection. -The result of the evaluation of the tree:path, is the value that must be compared to the tree:value. - -Every tree:Relation MAY provide a tree:remainingItems. A client MAY use tree:remainingItems to estimate the completeness of the downloaded elements to the end-user. - -Note: When traversing, a client SHOULD keep a list of already visited pages, as despite this being the TREE spec, circular references and back-links are not explicitly prohibited. - -A tree:import MAY be defined in the tree:Relation instance. When there is a tree:path defined, and when the relation is flagged interesting to follow, the import link needs to be downloaded in order to find the necessary literals to be compared (it is thus already a tree:ConditionalImport. - -Note: An example of a tree:import is given [in the repository](https://github.com/TREEcg/specification/blob/master/examples/geospatially-ordered-public-transport/first.ttl#L27). - -When dereferencing the object of a tree:node triple, the client MUST follow redirects. The URL to be used as the tree:Node URL is the last URL after redirects. - -Note: This enables rebalancing search trees. - -## Fallbacks ## {#fallbacks} - -When there is no tree:view triple provided, a client MUST use the tree:Collection from the previous page and still continue extracting members, and extract further relations defined on the current page URL. - -When there are no tree:members and/or no tree:Collection defined, then still a tree:Relation can be defined. The tree:path in the tree:Relation then refers to a pattern that can start from every triple in the page. - -When no tree:path is defined, the tree:value MUST be compared to all members’ triples that *can be compared to* the tree:value as defined by the type of the relation (or when no members or collection are defined, on every triple in the page). -When due to rdfs:range incompatibility, the object cannot be compared, the object will not be considered for comparison. - -Note: This may enable server developers to indicate an index on all literals of the members (e.g., a prefix relation on title, description and body text) without having to indicate all of the alternative paths in the tree:path. - -The target object of a tree:path SHOULD be materialized in the current Node document, but when it is not, the object MAY be considered implicit on the condition both tree:path and tree:member are defined. -In contrast to sh:path, a tree:path MAY refer to an implicit property and may not be materialized in the current response. This may break SPARQL processors that did not yet come across the object before in their query plan. However, the tree may still be useful for query processors that, for example, prioritize queries according to the user’s location, and first download nodes that are nearby the user. Therefore, the materialized location of the object is not needed. While not recommended, possible heuristics could try to infer the data, could try to fetch it through another tree:Collection, or retrieve it using URI dereferencing. - -## Specific relations ## {#relationsubclasses} - -When the *only* type given for a certain Relation is tree:Relation, then the client must dereference all of the nodes. While this may seem useless, it can be used for the same use case as a hydra:PartialCollectionView. - -For other types check the chapter on relation types in the vocabulary [](#Relation). - -### Comparing strings ### {#strings} - -String values have three specific type of relations: the tree:PrefixRelation, the tree:SubstringRelation and the tree:SuffixRelation. - -Note: We experimented with server-chosen locales such that ça suffit can also be found when following a tree:PrefixRelation with a tree:value "c" (which at this moment is not supported). That would require an understanding of locales, and [browser/JavaScript support for locales is too low to be useful at this point](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_identification_and_negotiation). - -Also the comparator relations such as tree:GreaterThanRelation can be used. -The strings MUST then be compared according to *case sensitive unicode ordering*. - -When a tree:path is defined, mind that you also may have to check the language of the element using the property shacl:inLanguage -More languages MAY be set. -When no language is set, all strings are compared. - -Note: If you want to have one resource containing both e and é as a prefix, you will have to create multiple relations to the same tree:Node. - -### Comparing named nodes ### {#named-nodes} - -When using comparator relations such as tree:GreaterThanRelation, named nodes must be compared as defined in the [ORDER BY section of the SPARQL specification](https://www.w3.org/TR/sparql11-query/#modOrderBy). - -### Comparing geospatial features ### {#geospatial} - -The tree:GeospatiallyContainsRelation is the relation than can be used to express all further members will be contained within a geospatial region defined by the WKT String in the tree:value. - -When using tree:GeospatiallyContainsRelation, the tree:path MUST refer to a literal containing a WKT string, such as geosparql:asWKT. - -### Comparing time literals ### {#time} - -When using relations such as tree:LessThanRelation or tree:GreaterThanRelation, the time literals need to be compared according to these 3 possible data types: xsd:date, xsd:dateTime or xsd:dateTimeStamp. - diff --git a/specs/3-search.md b/specs/3-search.md deleted file mode 100644 index 2d7ea5a..0000000 --- a/specs/3-search.md +++ /dev/null @@ -1,83 +0,0 @@ -# Search forms # {#searching} - -Searching through a TREE will allow you to immediately jump to the right tree:Node. -TREE relies on the [Hydra search specification](http://www.hydra-cg.com/spec/latest/core/#hydra:search) for its search forms. -It does however extend Hydra with specific search properties (hydra:IriTemplate) for different types of search forms, and searches starting from a tree:ViewDescription, to which the search form is linked with tree:search. -The behaviour of the search form fully depends on the specific property, for which TREE introduces a couple of specific properties: - -## Geospatial XYZ tiles search form ## {#xyztiles} - -Three properties allow to specify a geospatial XYZ tiles template (also known as slippy maps). - 1. tree:longitudeTile describes the X value - 2. tree:latitudeTile descrbes the Y value - 3. tree:zoom describes the zoom level - -All properties expect positive integers. - -
- ```turtle - a tree:Collection ; - dcterms:title "A prototype tree:Collection for Linked OpenStreetMap’s roads"@en ; - tree:view . - - a tree:Node ; - tree:viewDescription . - - a tree:ViewDescription ; - tree:search [ - a hydra:IriTemplate ; - hydra:template "https://tiles.openplanner.team/planet/20201103-095900/{z}/{x}/{y}" ; - hydra:variableRepresentation hydra:BasicRepresentation ; - hydra:mapping [ - a hydra:IriTemplateMapping ; - hydra:variable "x"; - hydra:property tree:longitudeTile; - hydra:required true - ],[ - a hydra:IriTemplateMapping ; - hydra:variable "y"; - hydra:property tree:latitudeTile; - hydra:required true - ],[ - a hydra:IriTemplateMapping ; - hydra:variable "z"; - hydra:property tree:zoom; - hydra:required true - ] - ] . - - ``` -
- -This search form describes a specific search form that uses a quad tree. The zoom level describes the depth, the longitudeTile and latitudeTile describe the x and y index of the fragmentation. (e.g., on zoom level 0, there’s 1 tile, on zoom level 1, there are 4 tiles, etc.). - -## Searching through a list of objects ordered by time ## {#timesearch} - -Same as the previous example but with the predicate tree:timeQuery expecting an xsd:dateTime. -This time however, when the page itself does not exist, a redirect is doing to happen to the page containing the timestamp. -A tree:path can indicate the time predicate which is intended. - -
- ```turtle - a tree:Collection ; - dcterms:title "An example collection with a time search view"@en ; - tree:view . - - a tree:Node ; - tree:viewDescription . - - a tree:ViewDescription ; - tree:search [ - a hydra:IriTemplate ; - hydra:template "https://example.org/{generatedAt}" ; - hydra:variableRepresentation hydra:BasicRepresentation ; - hydra:mapping [ - a hydra:IriTemplateMapping ; - hydra:variable "generatedAt"; - tree:path prov:generatedAtTime; - hydra:property tree:timeQuery; - hydra:required true - ] - ] . - ``` -
diff --git a/specs/5-imports.md b/specs/5-imports.md deleted file mode 100644 index c996b8c..0000000 --- a/specs/5-imports.md +++ /dev/null @@ -1,18 +0,0 @@ -# Imports # {#imports} - -A tree:import can be defined on multiple levels. When defined as part of a tree:Node, this document always needs to be fetched when processing this Node. -When defined as part of the tree:Relation, one MUST fetch the import when the relation needs to be correctly evaluated (e.g., the resulting page contains elements without materialized WKT strings, which however can be fetched from the import). -When importing a file, no hypermedia relations will be followed from that import in order to get more data. - -A tree:importStream can also be defined for providing a pubsub interface for subscribing to real-time updates. The object SHOULD be a [[!websockets]] or Server-Sent Events ([[!eventsource]]). - -Instead of tree:import, one can also use tree:conditionalImport which links to an object of the type tree:ConditionalImport with these properties: - - * tree:import with a link to the page to import, or a tree:importStream with a pubsub stream to import (optionally) - * tree:path with a property path that indicates the resource that elements in the imported resource contain - -Note: imports are powerful to keep recurring objects in a separate, more cacheable, resource. - -No hypermedia controls in the body MUST be interpreted in the imported resource and the object must be fully contained within that information resource. - -On the resources to import, Memento [[!RFC7089]] controls MAY be provided for historic versions. \ No newline at end of file diff --git a/specs/6-compatibility.md b/specs/6-compatibility.md deleted file mode 100644 index 3904bff..0000000 --- a/specs/6-compatibility.md +++ /dev/null @@ -1,117 +0,0 @@ -# Compatibility # {#compatibility} - -## DCAT ## {#dcat} - -[[!VOCAB-DCAT-2]] is the standard for Open Data Portals by W3C. In order to find TREE compliant datasets in data portals, there SHOULD be a dcat:endpointDescription from the dcat:DataService to the entrypoint where the tree:Collections and the tree:ViewDescriptions are listed. Furthermore, there SHOULD be a dct:conformsTo this URI: https://w3id.org/tree/specification. - -## Hydra ## {#hydra} - -A tree:Collection is compatible with the [Hydra Collections specification](https://www.hydra-cg.com/spec/latest/core/#collections). However, instead of hydra:view, we use tree:view and do not link to a hydra:PartialCollectionView but to a tree:Node. -A hydra:Collection can thus also be extended with a tree:shape and tree:view. -When this is done, also hydra:member can be used instead of tree:member. - -hydra:totalItems can be used to indicate the total amount of elements in the collection. -Hydra paging controls such as hydra:next and hydra:previous are semantically equivalent to a tree:Relation element that only contains a tree:node property. - -## Activity Streams 2.0 ## {#activitystreams} - -A tree:Collection is also compatible with [[!activitystreams-core]]’s specification of [paged collections](https://www.w3.org/TR/activitystreams-core/#collections). -Instead of dcterms:isPartOf, also as:partOf can be used to indicate that the current page is part of the full collection. -While Hydra and TREE link to the members of the collection by using the specific collection as a subject, Activity Streams 2.0 (AS) indicates a member starting from the page URL. -Therefore, when using AS collections, a client implementation should gather the members from the tree:Node or as:CollectionPage instead. - -as:totalItems can be used to indicate the total amount of elements in the collection. - -AS paging controls such as as:nextand as:previous are semantically equivalent to a tree:Relation element that only contains a tree:node property. - -## LDP Containers ## {#ldp} - -In [[!LDP]], the tree:view can be applied on top of the ldp:Container instance. -Members can be found through ldp:contains, and/or through the indirect ldp:membershipResource and ldp:hasMemberRelation or ldp:isMemberOfRelation construct. - -If this container is paged by the [[!ldp-paging]] (chapter 7) spec, then this MUST be ignored. - -If there is an ordering, this MUST be ignored by TREE clients (the relations contain all necessary information for pruning). - -## Shape trees ## {#shapetrees} - -[The Shape Trees specification](https://shapetrees.org/TR/specification/) is specifically built to work within existing ecosystems. -As it was conceived to interoperate with LDP, the term Container in the Shape Trees spec can also be interpreted as a tree:Collection. -Shape Trees can help in the source selection of what specific tree:Collection to pick for your goal, and may add hierarchies to a set of tree:Collections. -A client MAY infer a tree:shape of the collection through the st:validatedBy property of the Shapes Tree. - -An example of a collection using Shape Tree terms. In this example a sensor with some observations is validated by using a [Shape Expressions](http://shex.io/shex-semantics/) (ShEx) file. - -
- ```turtle - @prefix sosa: . - @prefix om: . - @prefix ldp: . - - <2021.ttl#Collection> a ldp:Container; - st:validatedBy ; - tree:member , . - - - a sosa:Sensor; - sosa:madeObservation - , - ; - sosa:observes om:Temperature . - - - a sosa:Observation; - sosa:observedProperty om:Temperature; - sosa:madeBySensor ; - sosa:hasResult ; - sosa:resultTime "2020-08-25T07:05:31Z"^^xsd:dateTime . - - a om:Measure; - om:hasValue "22"^^xsd:float; - om:hasUnit om:degreeCelsius . - - - a sosa:Observation; - sosa:observedProperty om:Temperature; - sosa:madeBySensor ; - sosa:hasResult ; - sosa:resultTime "2020-08-25T07:05:32Z"^^xsd:dateTime . - - a om:Measure; - om:hasValue "22"^^xsd:float; - om:hasUnit om:degreeCelsius . - - - a sosa:Sensor; - sosa:observes om:Temperature . - ``` - - And its corresponding ShEx file (called Sensor.shex) - - ```shex - PREFIX sosa: - PREFIX xsd: - PREFIX om: - PREFIX rdfs: - - <#Sensor> { - a [sosa:Sensor] ; - sosa:observes [om:Temperature] ; - sosa:madeObservation @<#TemperatureObservation> * - } - - <#TemperatureObservation> { - a [sosa:Observation] ; - sosa:resultTime xsd:dateTime ; - sosa:madeBySensor @<#Sensor> ? ; - sosa:observedProperty [om:Temperature]; - sosa:hasResult @<#TemperatureResult> - } - - <#TemperatureResult> { - a [om:Measure]; - om:hasValue xsd:float ; - om:hasUnit [om:degreeCelsius] - } - ``` -
From 723dd1f7458aee03a7bc35d8989363f85117209a Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Wed, 5 Jun 2024 10:50:06 +0200 Subject: [PATCH 02/28] Fix specs --- .github/workflows/Build-TREE-spec.yml | 2 +- spec.bs => 01-tree-specification.bs | 62 +-------------------------- 2 files changed, 2 insertions(+), 62 deletions(-) rename spec.bs => 01-tree-specification.bs (87%) diff --git a/.github/workflows/Build-TREE-spec.yml b/.github/workflows/Build-TREE-spec.yml index dd56a1b..350209f 100644 --- a/.github/workflows/Build-TREE-spec.yml +++ b/.github/workflows/Build-TREE-spec.yml @@ -21,7 +21,7 @@ jobs: # if your doc isn’t in the root folder, # or Bikeshed otherwise can’t find it: - SOURCE: spec.bs + SOURCE: 01-tree-specification.bs # output filename defaults to your input # with .html extension instead, diff --git a/spec.bs b/01-tree-specification.bs similarity index 87% rename from spec.bs rename to 01-tree-specification.bs index d930d94..fcb4ab0 100644 --- a/spec.bs +++ b/01-tree-specification.bs @@ -19,7 +19,7 @@ Abstract: # Overview # {#overview} -An overview of the TREE specification with the TREE collection, a reference to the first focus node of its members, and the relations to other nodes from the current node. +An overview of the TREE specification with the TREE collection, a reference to the first focus node of its members, and the relations to other nodes from the current node. The TREE specification introduces these core concepts: * a tree:Collection is a subclass of dcat:Dataset ([[!vocab-dcat-3]]). The specialization being that it is a DCAT dataset a collection of members. It typically has these properties when described in a node: @@ -130,66 +130,6 @@ The latter uses the sh:NodeShape from the tree:shape p Note: The way we process SHACL shapes into Shape Template is important to understand in order to know when an HTTP request will be triggered when designing SHACL shapes. A cardinality constraint not being exactly matched or a sh:pattern not being respected will not trigger an HTTP request, and instead just add the invalid quads to the Member. This is a design choice: we only define triggers for HTTP request from the SHACL shape to come to a complete set of quads describing the member the data publisher pointed at using tree:member. -# Discovery and source selection# {#hypermedia} - -TREE tackles discovery and source selection on three levels: i) interface discovery, ii) view discovery, and iii) dataset discovery. -Interface discovery discovers what collection the current page is part of, and discovers what the next possible HTTP requests are through relations and search forms. -One dataset can have multiple views that can be published across different servers, selecting one for a certain use case is part of the view discovery. -Dataset discovery is then selecting a tree:Collection of interest. - - -## Interface discovery ## {#interface-discovery} - -Interface discovery starts when a URL is provided to a specific tree:Node. -A node from which all members of a collection can be discovered (an “entry node”), can be found through a triple stating ex:C1 tree:view ex:N1 with ex:C1 being a tree:Collection and ex:N1 being a tree:Node. - -When the current page is a tree:Node, there MUST be a property linking the current page URL to the URI of the tree:Collection. However, not from all tree:Nodes all members can be reached, and therefore 2 other properties can be used: void:subset, or the inverse property, dcterms:isPartOf. - -ex:C1 tree:view <> . links the current page to the tree:Collection. - -We refer to next chapters for traversing across multiple relations, or for using search forms. - -## View discovery ## {#multiple-views} - -Todo: This will be reworked - -Note: How a client picks the right view is use case specific. The tree:ViewDescription’s properties can help in that regards. - -In order to prioritize a specific view link, the relations and search forms in the entry nodes can be studied for their relation types, path or remaining items. -The class tree:ViewDescription indicates a specific TREE structure on a tree:Collection. -Through the property tree:viewDescription a tree:Node can link to an entity that describes the view, and can be reused in data portals as the dcat:DataService. - -
- ```turtle - ## What can be found in a tree:Node - ex:N1 a tree:Node ; - tree:viewDescription ex:View1 . - - ex:C1 a tree:Collection ; - tree:view ex:N1 . - - ## What can be found on a data portal - ex:C1 a dcat:Dataset . - ex:View1 a tree:ViewDescription, dcat:DataService ; - dcat:endpointURL ex:N1 ; # The entry point that can be advertised in a data portal - dcat:servesDataset ex:C1 . - ``` -
- -When there is no tree:viewDescription property in this page, a client either already discovered the description of this view in an earlier tree:Node, either the current tree:Node is implicitly the ViewDescription. Therefore, when the property path tree:view → tree:viewDescription does not yield a result, the view properties MUST be extracted from the object of the tree:view triple. -A tree:Node can also be double typed as the tree:ViewDescription. A client must thus check for ViewDescriptions on both the current node without the tree:viewDescription qualification, as on the current node with the tree:viewDescription link. - - -## Dataset discovery ## {#multiple-collections} - -When multiple collections are found by a client, it can choose to prune the collections based on the tree:shape property. -Therefore a data publisher SHOULD annotate a tree:Collection instance with a SHACL shape. -The tree:shape points to a SHACL description of the shape (sh:NodeShape). - -Note: the shape can be a blank node, or a named node on which you should follow your nose when it is defined at a different HTTP URL. - -Note: For compatibility with the [Solid specifications](https://solidproject.org/TR/), a ShEx shape may also be given (see the chapter on compatibility bellow). - # The tree:Relations # {#relations} The initial configuration of the tree:Collection and the description of the view is always provided when the view has been discovered, either in a separate document describing the view, either in the entry node itself. The configuration MUST be reused on any subsequent tree:Node. From 1a528e7ab31156d88118ae3903ea705119b69203 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Wed, 5 Jun 2024 13:26:58 +0200 Subject: [PATCH 03/28] Shape templates to topologies --- 01-tree-specification.bs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/01-tree-specification.bs b/01-tree-specification.bs index fcb4ab0..3a6b370 100644 --- a/01-tree-specification.bs +++ b/01-tree-specification.bs @@ -124,11 +124,11 @@ A tree:search form is an IRI template, that when filled out with th ## The member extraction algorithm ## {#member-extraction-algorithm} -The set of quads the are part of the member, are defined by the [shape templates algorithm](https://w3id.org/tree/specification/shape-templates), provided as a separate report to this specification. -It is a combination of Concise Bounded Descriptions, named graphs and Shape Templates. +The set of quads the are part of the member, are defined by the [shape topology algorithm](https://w3id.org/tree/specification/shape-topologies), provided as a separate report to this specification. +It is a combination of Concise Bounded Descriptions, named graphs and Shape Topologies. The latter uses the sh:NodeShape from the tree:shape property on the collections as an indication of the topology of the member graph. -Note: The way we process SHACL shapes into Shape Template is important to understand in order to know when an HTTP request will be triggered when designing SHACL shapes. A cardinality constraint not being exactly matched or a sh:pattern not being respected will not trigger an HTTP request, and instead just add the invalid quads to the Member. This is a design choice: we only define triggers for HTTP request from the SHACL shape to come to a complete set of quads describing the member the data publisher pointed at using tree:member. +Note: The way we process SHACL shapes into Shape Topology is important to understand in order to know when an HTTP request will be triggered when designing SHACL shapes. A cardinality constraint not being exactly matched or a sh:pattern not being respected will not trigger an HTTP request, and instead just add the invalid quads to the Member. This is a design choice: we only define triggers for HTTP request from the SHACL shape to come to a complete set of quads describing the member the data publisher pointed at using tree:member. # The tree:Relations # {#relations} From dbdbd6646e14301b894d7364daac93dbf7cadee2 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Wed, 5 Jun 2024 13:33:10 +0200 Subject: [PATCH 04/28] abstract fix --- 01-tree-specification.bs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/01-tree-specification.bs b/01-tree-specification.bs index 3a6b370..a10e1c1 100644 --- a/01-tree-specification.bs +++ b/01-tree-specification.bs @@ -11,10 +11,10 @@ Mailing List: public-treecg@w3.org Mailing List Archives: https://lists.w3.org/Archives/Public/public-treecg/ Editor: Pieter Colpaert, https://pietercolpaert.be Abstract: - The TREE hypermedia specification enables data publishers and API developers to describe datasets as collections of entities, called “the members”. - It then allows to create one or more views of this collection. - A view allows organizing the members into multiple pages or nodes, and these nodes are interlinked using relations and/or search forms. - This way, a user agent that can interpret the TREE hypermedia controls can find the most efficient way to the members of interest to them. + The TREE hypermedia specification enables data publishers and API developers to describe datasets as collections of entity descriptions, referred to as “members”. + It supports the creation of one or more views of this collection. + These views organize the members into multiple pages or nodes, which are interlinked using relations and/or search forms. + Consequently, a user agent that can interpret the TREE hypermedia controls can efficiently navigate to the members of interest. # Overview # {#overview} From 0e29b2c38793f26699cf4542cc3119b677ec2a0a Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Wed, 5 Jun 2024 13:49:06 +0200 Subject: [PATCH 05/28] DCAT to discovery --- 01-tree-specification.bs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/01-tree-specification.bs b/01-tree-specification.bs index a10e1c1..cd97542 100644 --- a/01-tree-specification.bs +++ b/01-tree-specification.bs @@ -22,10 +22,10 @@ Abstract: An overview of the TREE specification with the TREE collection, a reference to the first focus node of its members, and the relations to other nodes from the current node. The TREE specification introduces these core concepts: - * a tree:Collection is a subclass of dcat:Dataset ([[!vocab-dcat-3]]). The specialization being that it is a DCAT dataset a collection of members. It typically has these properties when described in a node: + * a tree:Collection is a set of members. It typically has these properties when described in a node: - tree:member points at the first focus node from which to retrieve and extract all quads of a member. - - tree:view points to the current tree:Node you’re visiting. - - tree:shape indicates the [[!SHACL]] shape to which each member in the collection adheres. + - tree:view points to the tree:Node you’re currently visiting. + - tree:shape indicates the [[!SHACL]] shape (exactly one) to which each member in the collection adheres. - tree:viewDescription links to a description of the view (a tree:ViewDescription). Multiple descriptions MAY be provided that MUST be combined. * a tree:Node: is a page on which relations to other pages are described through the tree:relation predicate, and/or through which a next tree:Node can be found by using the tree:search form. * a tree:Relation is a relation from one node to another. An extension of this class indicates a specific type of relation (e.g., a tree:GreaterThanRelation). A relation typically has these properties: @@ -33,7 +33,7 @@ The TREE specification introduces these core concepts: - a tree:path indicating to which of the members' properties this relation applies - a tree:value indicating a value constraint on the members' values - a tree:remainingItems defining how many members can be reached when following this relation - * a tree:ViewDescription is a subclass of dcat:DataService and serves a tree:Collection. + * a tree:ViewDescription can be used to have a general understanding of the current view: - a tree:search describes a search form that allows an agent to jump to a specific tree:Node. The first step when creating a TREE hypermedia interface is defining a collection of members: From 934a743b2fd3dc92d0e559104446143902dab42a Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Wed, 5 Jun 2024 13:53:08 +0200 Subject: [PATCH 06/28] Link from the main spec --- 01-tree-specification.bs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/01-tree-specification.bs b/01-tree-specification.bs index cd97542..d480073 100644 --- a/01-tree-specification.bs +++ b/01-tree-specification.bs @@ -104,6 +104,12 @@ From the moment this collection of members grows too large for one page, a fragm 4. By putting the triples in a named graph of the object of tree:member, all these triples will be matched. +The specification in this document is the starting point for traversing collection views. +There are two more reports published as part of this community group: + 1. The [shape topology algorithm](https://w3id.org/tree/specification/shape-topologies) + 2. [Discoverying tree:Collections and their views](https://w3id.org/tree/specification/discovery) + + # Definitions # {#formalizations} A tree:Collection is a set of tree:Members. The set of members MAY be empty. From 201b0c31eb429761b0b51a7c6a57c3f5d9e0a4e8 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Wed, 19 Jun 2024 14:06:45 +0200 Subject: [PATCH 07/28] Work in progress: search tree proposal --- .../workflows/Build-ShapeTopologies-spec.yml | 2 +- .github/workflows/Build-discovery-spec.yml | 29 +++++++ shape-topologies.bs => 02-shape-topologies.bs | 0 03-discovery-specification.bs | 87 +++++++++++++++++++ tree.ttl | 33 ++++--- vocabulary.md | 12 ++- 6 files changed, 143 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/Build-discovery-spec.yml rename shape-topologies.bs => 02-shape-topologies.bs (100%) create mode 100644 03-discovery-specification.bs diff --git a/.github/workflows/Build-ShapeTopologies-spec.yml b/.github/workflows/Build-ShapeTopologies-spec.yml index d78d0b7..00b49b5 100644 --- a/.github/workflows/Build-ShapeTopologies-spec.yml +++ b/.github/workflows/Build-ShapeTopologies-spec.yml @@ -21,7 +21,7 @@ jobs: # if your doc isn’t in the root folder, # or Bikeshed otherwise can’t find it: - SOURCE: shape-topologies.bs + SOURCE: 02-shape-topologies.bs # output filename defaults to your input # with .html extension instead, diff --git a/.github/workflows/Build-discovery-spec.yml b/.github/workflows/Build-discovery-spec.yml new file mode 100644 index 0000000..9492308 --- /dev/null +++ b/.github/workflows/Build-discovery-spec.yml @@ -0,0 +1,29 @@ +name: Build TREE discovery spec +on: + workflow_dispatch: {} + pull_request: {} + push: + branches: [master] +jobs: + main: + name: Build, Validate and Deploy + runs-on: ubuntu-20.04 + permissions: + contents: write + steps: + - uses: actions/checkout@v3 + - uses: w3c/spec-prod@v2 + with: + TOOLCHAIN: bikeshed + + # Modify as appropriate + GH_PAGES_BRANCH: gh-pages + + # if your doc isn’t in the root folder, + # or Bikeshed otherwise can’t find it: + SOURCE: 03-discovery-specification.bs + + # output filename defaults to your input + # with .html extension instead, + # but if you want to customize it: + DESTINATION: discovery.html \ No newline at end of file diff --git a/shape-topologies.bs b/02-shape-topologies.bs similarity index 100% rename from shape-topologies.bs rename to 02-shape-topologies.bs diff --git a/03-discovery-specification.bs b/03-discovery-specification.bs new file mode 100644 index 0000000..ea0b4cc --- /dev/null +++ b/03-discovery-specification.bs @@ -0,0 +1,87 @@ + + +# The overview # {#overview} + +A tree:Collection is a subclass of dcat:Dataset ([[!vocab-dcat-3]]). +The specialization being that it is a DCAT dataset with a collection of _members_. + +A tree:ViewDescription is a subClassOf dcat:DataService and serves a tree:Collection. + +A tree:View is a subClassOf dcat:Distribution. + +A TREE client MUST be provided with a URL to start from, which we call the entrypoint. +This entrypoint MUST be one of the following: + 1. a `tree:RootNode`, + 2. a `tree:SearchTree` + 3. a `tree:Collection`, or + 4. a `dcat:Catalog` + +# Initializing a client with a url to a... # {#starting-from} + +## tree:RootNode ## {#rootnode} + +A node from which all members of a collection can be found is a `tree:RootNode`, which MAY be explicitely typed as such. +When the URL given to the TREE client, after all redirects, is used in a triple ex:C1 tree:view <> ., a client MUST assume the URL after redirects is an identifier of a `tree:RootNode` of the collection `ex:C1`. + +## tree:SearchTree ## {#searchtree} + +A `tree:SearchTree` is a subClassOf `dcat:Distribution` and distributes one specific `tree:Collection`. +When dereferencing a URL identifying a Search Tree, a server MUST respond with one of the following options: + 1. The `tree:RootNode` of the search tree is returned. On that page, the URI of the `tree:SearchTree` MUST be mentioned in one of the following ways: + * The `tree:RootNode` MAY describe it has a `tree:viewDescription` being the `tree:SearchTree` + * It MAY simply be double typed with the `tree:RootNode` (in which the former chapter is applicable) + 2. A DCAT-based overview of the distribution(s). In this case, the client MUST look for the URL it requested, and check whether there is a property `dcat:accessURL` + +Through the direct property `tree:rootNode` (subPropertyOf `dcat:accessURL`) one can find the `tree:RootNode`, for which we can then continue with the example above. + +Catalog + + +## tree:Collection ## {#collection} + +In order to prioritize a specific view link, the relations and search forms in the entry nodes can be studied for their relation types, path or remaining items. +The class tree:ViewDescription indicates a specific TREE structure on a tree:Collection. +Through the property tree:viewDescription a tree:Node can link to an entity that describes the view, and can be reused in data portals as the dcat:DataService. + +
+ ```turtle + ## What can be found in a tree:Node + ex:N1 a tree:Node ; + tree:viewDescription ex:View1 . + + ex:C1 a tree:Collection ; + tree:view ex:N1 . + + ## What can be found on a data portal + ex:C1 a dcat:Dataset . + ex:View1 a tree:ViewDescription, dcat:DataService ; + dcat:endpointURL ex:N1 ; # The entry point that can be advertised in a data portal + dcat:servesDataset ex:C1 . + ``` +
+ +When there is no tree:viewDescription property in this page, a client either already discovered the description of this view in an earlier tree:Node, either the current tree:Node is implicitly the ViewDescription. Therefore, when the property path tree:view → tree:viewDescription does not yield a result, the view properties MUST be extracted from the object of the tree:view triple. +A tree:Node can also be double typed as the tree:ViewDescription. A client must thus check for ViewDescriptions on both the current node without the tree:viewDescription qualification, as on the current node with the tree:viewDescription link. + +## dcat:Catalog ## {#collection} + +When multiple collections are found by a client, it can choose to prune the collections based on the tree:shape property. +Therefore a data publisher SHOULD annotate a tree:Collection instance with a SHACL shape. +The tree:shape points to a SHACL description of the shape (sh:NodeShape). + +Note: the shape can be a blank node, or a named node on which you should follow your nose when it is defined at a different HTTP URL. diff --git a/tree.ttl b/tree.ttl index 7c82975..d9ff39c 100644 --- a/tree.ttl +++ b/tree.ttl @@ -23,15 +23,13 @@ tree: a foaf:Document ; foaf:primaryTopic tree:Ontology; cc:license ; - dct:creator , . + dct:creator . foaf:name "Pieter Colpaert"; foaf:mbox "pieter.colpaert@ugent.be". - foaf:name "Ruben Taelman" . - tree:Ontology a owl:Ontology ; rdfs:label "TREE"@en; - rdfs:comment "A hypermedia specification for fragmenting collections."@en. + rdfs:comment "A hypermedia specification for fragmenting collections of members."@en. ######## Classes @@ -40,15 +38,19 @@ tree:Collection a rdfs:Class ; rdfs:label "Collection"@en; rdfs:comment "A tree:Collection is a collection containing members. The members may be spread across multiple tree:Nodes."@en . -tree:ViewDescription a rdfs:Class ; - rdfs:subClassOf dcat:DataService ; - rdfs:label "View Description"@en ; - rdfs:comment "Describes a specific TREE structure on top of the tree:Collection"@en . +tree:SearchTree a rdfs:Class ; + rdfs:subClassOf dcat:Distribution ; + rdfs:label "Search Tree"@en; + rdfs:comment "A tree:SearchTree publishes the members of a collection."@en . tree:Node a rdfs:Class ; rdfs:label "Node"@en; rdfs:comment "A tree:Node is a node that may contain relations to other nodes."@en . +tree:RootNode a rdfs:Class ; + rdfs:label "Root Node"@en; + rdfs:comment "A tree:RootNode is the access point into a search tree."@en . + tree:Relation a rdfs:Class ; rdfs:label "Relation"@en ; rdfs:comment "A class describing the relation between two nodes"@en. @@ -96,7 +98,7 @@ tree:EqualToRelation a rdfs:Class ; tree:NotEqualToRelation a rdfs:Class ; rdfs:subClassOf tree:Relation ; - rdfs:label "Not equal To Relation"@en . + rdfs:label "Not Equal To Relation"@en . tree:GeospatiallyContainsRelation a rdfs:Class ; rdfs:subClassOf tree:Relation ; @@ -112,9 +114,9 @@ tree:InBetweenRelation a rdfs:Class ; tree:viewDescription a rdf:Property ; rdfs:label "View Description"; - rdfs:comment "Links together a tree:Node with its description of this TREE structure"@en; - rdfs:domain tree:Node ; - rdfs:range tree:ViewDescription . + rdfs:comment "Links together a tree:Node with a description of this search tree through the search tree itself or through a data service"@en; + rdfs:domain tree:Node . + #rdfs:range owl:oneOf ( tree:SearchTree dcat:DataService ) . # Just leaving the range open for now tree:relation a rdf:Property ; rdfs:label "Relation"@en; @@ -134,6 +136,13 @@ tree:node a rdf:Property ; rdfs:domain tree:Relation; rdfs:range tree:Node. +tree:rootNode a rdf:Property ; + rdfs:subPropertyOf dcat:accessURL ; + rdfs:label "Has Root Node"@en; + rdfs:comment "A view has a root node that can be used to start traversing the search tree"@en; + rdfs:domain tree:View ; + rdfs:range tree:RootNode . + tree:value a rdf:Property ; rdfs:label "Value"@en ; rdfs:comment "The value the node linked in the node relation is compared to"@en . diff --git a/vocabulary.md b/vocabulary.md index b1b1beb..cb413a3 100644 --- a/vocabulary.md +++ b/vocabulary.md @@ -22,6 +22,10 @@ A collection has members that may adhere to a certain shape. A tree:Node is a node that may contain links to other dereferenceable resources that lead to a full overview of a tree:Collection. +### tree:RootNode ### {#RootNode} + +### tree:SearchTree ### {#SearchTree} + ### tree:Relation ### {#Relation} An entity that describes a relation between two tree:Nodes. @@ -44,10 +48,6 @@ The tree:Relation has specific sub-classes that implement a more sp A class to import a file or a stream based on a tree:path of properties. This way it can import the necessary data for complying to the SHACL shape, or evaluating a relation type. -### tree:ViewDescription ### {#ViewDescription} - -Describes a specific TREE structure on top of the tree:Collection. - ## Properties ## {#properties} ### tree:relation ### {#relation} @@ -151,8 +151,6 @@ A search form parameter: accompagnied by a tree:path, it indicates ### tree:viewDescription ### {#viewDescription} -Links together a tree:Node with its description of this TREE structure. +Links together a tree:Node with a description that needs to be taken into account **Domain**: tree:Node - -**Range**: tree:ViewDescription From 281159ed619a3a35cba52a02ee3ee001d12250fd Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Sun, 1 Sep 2024 09:45:32 +0200 Subject: [PATCH 08/28] Rework spec to client-centric and remove fallbacks --- 01-tree-specification.bs | 161 +++++++++++++++------------------- 03-discovery-specification.bs | 64 ++++++++------ tree.ttl | 1 - vocabulary.md | 20 ++++- 4 files changed, 127 insertions(+), 119 deletions(-) diff --git a/01-tree-specification.bs b/01-tree-specification.bs index d480073..2b1f36e 100644 --- a/01-tree-specification.bs +++ b/01-tree-specification.bs @@ -11,32 +11,32 @@ Mailing List: public-treecg@w3.org Mailing List Archives: https://lists.w3.org/Archives/Public/public-treecg/ Editor: Pieter Colpaert, https://pietercolpaert.be Abstract: - The TREE hypermedia specification enables data publishers and API developers to describe datasets as collections of entity descriptions, referred to as “members”. - It supports the creation of one or more views of this collection. - These views organize the members into multiple pages or nodes, which are interlinked using relations and/or search forms. - Consequently, a user agent that can interpret the TREE hypermedia controls can efficiently navigate to the members of interest. + TREE hypermedia describes the pagination of a collection of entity descriptions. + It allows clients to follow their nose through a search tree based information structure. # Overview # {#overview} An overview of the TREE specification with the TREE collection, a reference to the first focus node of its members, and the relations to other nodes from the current node. - +
The TREE specification introduces these core concepts: * a tree:Collection is a set of members. It typically has these properties when described in a node: - - tree:member points at the first focus node from which to retrieve and extract all quads of a member. - - tree:view points to the tree:Node you’re currently visiting. - - tree:shape indicates the [[!SHACL]] shape (exactly one) to which each member in the collection adheres. - - tree:viewDescription links to a description of the view (a tree:ViewDescription). Multiple descriptions MAY be provided that MUST be combined. - * a tree:Node: is a page on which relations to other pages are described through the tree:relation predicate, and/or through which a next tree:Node can be found by using the tree:search form. + - tree:member points at the first focus node from which to retrieve and extract all quads of a member + - tree:view points to the tree:Node you’re currently visiting + - tree:shape indicates the [[!SHACL]] shape (exactly one) to which each member in the collection adheres + * a tree:Node: is a page in the search tree + - `tree:relation` points at relations to other node + - a tree:search describes a search form that allows an agent to jump to a specific tree:Node in the (sub)tree from here. + - tree:viewDescription links a description of (such as a tree:SearchTree, a `dcat:Distribution`, a `dcat:DataService`) * a tree:Relation is a relation from one node to another. An extension of this class indicates a specific type of relation (e.g., a tree:GreaterThanRelation). A relation typically has these properties: - a tree:node the URL of the other node - a tree:path indicating to which of the members' properties this relation applies - a tree:value indicating a value constraint on the members' values - a tree:remainingItems defining how many members can be reached when following this relation - * a tree:ViewDescription can be used to have a general understanding of the current view: - - a tree:search describes a search form that allows an agent to jump to a specific tree:Node. + * a tree:SearchTree is this collection of nodes. The SearchTree can be double typed with the root `tree:Node`, but can also be linked through the property `tree:viewDescription`. -The first step when creating a TREE hypermedia interface is defining a collection of members: +A simple collection can be created as illustrated in the following example: +
```turtle @@ -54,7 +54,10 @@ The first step when creating a TREE hypermedia interface is defining a collectio ```
-From the moment this collection of members grows too large for one page, a fragmentation needs to be created in which an initial set of member can be found on an entry node, and more members can be found by interpreting the TREE hypermedia controls. This is illustrated by the next example: +From the moment this collection of members grows too large for one page, +a pagination needs to be created in which an initial set of members can be found through the rootnode, +and more members can be found by interpreting the TREE hypermedia controls. +This is illustrated in the next example:
```turtle @@ -73,13 +76,13 @@ From the moment this collection of members grows too large for one page, a fragm tree:path ex:value . ex:R1 a tree:LessThanRelation ; # This is very useful for a client that is looking for a value 10 or greater - tree:node ex:Node3 ; # This is the URL of another page + tree:node ex:Node3 ; tree:value 10; tree:remainingItems 7 ; tree:path ex:value . ex:R2 a tree:GreaterThanOrEqualToRelation ; - tree:node ex:Node4 ; # This is the URL of another page + tree:node ex:Node4 ; tree:value 10; tree:remainingItems 10 ; tree:path ex:value . @@ -94,90 +97,78 @@ From the moment this collection of members grows too large for one page, a fragm ```
-
- Thanks to the [member extraction algorithm](#member-extraction-algorithm), a data publisher can choose to define their members in different ways: - 1. As in the examples above: all quads with the object of the tree:member quads as a subject (and recursively the quads of their blank nodes) are by default included (see also [[!CBD]]), except when they would explicitely not be included in case 3, when the shape would be closed. - 2. Out of band / in band: - - when no quads of a member have been found, the member will be dereferenced. This allows to publish the member on a separate page. - - part of the member can be maintained elsewhere when a shape is defined (see 3) - 3. By defining a more complex shape with tree:shape, also nested entities can be included in the member - 4. By putting the triples in a named graph of the object of tree:member, all these triples will be matched. -
- -The specification in this document is the starting point for traversing collection views. -There are two more reports published as part of this community group: - 1. The [shape topology algorithm](https://w3id.org/tree/specification/shape-topologies) - 2. [Discoverying tree:Collections and their views](https://w3id.org/tree/specification/discovery) - - -# Definitions # {#formalizations} - -A tree:Collection is a set of tree:Members. The set of members MAY be empty. - -A tree:Member is a set of (at least one) quad(s) defined by the member extraction algorithm (next subsection). - -A tree:Node is a dereferenceable resource containing tree:Relations and a subset of () members of the collection. In a tree:Node, both the set of tree:Relations as the subset of members MAY be empty. The same member MAY be contained in multiple nodes. - -A tree:Relation is a function denoting a conditional link to another tree:Node. - -A tree:Node, apart from the root node, has exactly one other tree:Node linking into it through one or more relations. - -Note: The condition of multiple tree:Relations to the same tree:Node MUST be combined with a logical AND. +# Initialization # {#init} -A View is a specific set of interlinked tree:Nodes, that together contain all members in a collection. A specific view will adhere to a certain growth or tree balancing strategy. In one View, completeness MUST be guaranteed, unless the View has a retention policy which becomes possible in LDES. +A client SHOULD be initiated using a URL. +The client MUST dereference the URL, which will result in a set of [[!rdf-concepts]] triples or quads. +When the URL after all redirects, is used in a triple ?c tree:view <> ., a client MUST assume the URL after redirects is an identifier of the intended root node of the collection in `?c`. -A tree:search form is an IRI template, that when filled out with the right parameters becomes a tree:Node IRI, or when dereferenced will redirect to a tree:Node from which all members in the collection that adhere to the described comparator can be found. +Note: Dereferencing in this specification also means parsing the RDF triples or quads from the HTTP response. TREE does not limit the content-types that can be used to represent RDF triples. Client developers should do a best-effort for their community. -## The member extraction algorithm ## {#member-extraction-algorithm} +If there is no such triple, then the client MUST check whether the URL before redirects (`E`) has been used in a pattern ` tree:view ?N.` where there’s exactly one `?N`, then the algorithm MUST return `?N` as the rootnode and `E` as the collection. -The set of quads the are part of the member, are defined by the [shape topology algorithm](https://w3id.org/tree/specification/shape-topologies), provided as a separate report to this specification. -It is a combination of Concise Bounded Descriptions, named graphs and Shape Topologies. -The latter uses the sh:NodeShape from the tree:shape property on the collections as an indication of the topology of the member graph. +The client then MUST dereference the identified rootnode (if it did not do that already) and merge those quads with the already found quads. +It now MUST look for a potential search forms that MAY be linked, either i) on top of the rootnode, either ii) on top of the entity linked through `tree:viewDescription`, or iii) on the `tree:SearchTree` using `tree:search`. -Note: The way we process SHACL shapes into Shape Topology is important to understand in order to know when an HTTP request will be triggered when designing SHACL shapes. A cardinality constraint not being exactly matched or a sh:pattern not being respected will not trigger an HTTP request, and instead just add the invalid quads to the Member. This is a design choice: we only define triggers for HTTP request from the SHACL shape to come to a complete set of quads describing the member the data publisher pointed at using tree:member. +The resulting collection IRI `C`, the rootnode IRI `R`, list of already visited pages `H` (and optionally their time to live), current quads `Q` and search forms `S`. -# The tree:Relations # {#relations} +In case it is not done using an unambiguous URL, clients MAY implement the report on [Discovery and Context Information (work in progress)](https://w3id.org/tree/specification/discovery). +This report also explains how clients MAY implement support for extracting context information such as provenance, contact points, etc. -The initial configuration of the tree:Collection and the description of the view is always provided when the view has been discovered, either in a separate document describing the view, either in the entry node itself. The configuration MUST be reused on any subsequent tree:Node. +Note: Having an identifier for the collection has become mandatory: without it you can otherwise not define completeness. -While discovering and traversing the interface, a client MUST take the descriptions on top of the Node, the View and the Collection with it. +# The member extraction algorithm # {#member-extraction-algorithm} -## Traversing relations ## {#traversing} +TODO: review motivation -A tree:Node element MAY have one or more tree:relation properties. A relation is an entity of the type tree:Relation, and MAY have a more specific type. A tree:Relation MUST have one tree:node object of the type tree:Node. By default, all nodes need to be followed, unless the client is able to select this relation for pruning (see next section). - -The tree:Relation’s tree:value SHOULD be set. The object of tree:value SHOULD be accompanied by a data type when it is a literal value. +
+Thanks to the member extraction algorithm, a data publisher can define their members in different ways: + 1. As in the examples above: all quads with the object of the tree:member quads as a subject (and recursively the quads of their blank nodes) are by default included (see also [[!CBD]]), except when they would explicitely not be included in case 3, when the shape would be closed. + 2. Out of band / in band: + - when no quads of a member have been found, the member will be dereferenced. This allows to publish the member on a separate page. + - part of the member can be maintained elsewhere when a shape is defined (see 3) + 3. By defining a more complex shape with tree:shape, also nested entities can be included in the member + 4. By putting the triples in a named graph of the object of tree:member, all these triples will be matched. +
-Every tree:Relation SHOULD have a tree:path, indicating the path from the member to the object on which the tree:Relation applies. For the different ways to express or handle a tree:path, we refer to [2.3.1 in the shacl specification](https://www.w3.org/TR/shacl/#x2.3.1-shacl-property-paths). All possible combinations of e.g., shacl:alternativePath, shacl:inversePath or shacl:inLanguage in the SHACL spec can be used. When shacl:alternativePath is used, the order in the list will define the importance of the order when evaluating the tree:Relation. A wildcard in the path is limited to the tree:shape of the tree:Collection. -The result of the evaluation of the tree:path, is the value that must be compared to the tree:value. +Depending on the goals of the client, it MAY implement the member extraction algorithm. +It MUST implement the algorithm in case the goal is to find the complete and finite set of quads that are part of a member as intended by the data publisher. +The method used withun TREE is combination of Concise Bounded Descriptions, named graphs and the topology of a shape (deducted from the `tree:shape`). +The full algorithm is specificied in the [shape topologies](https://w3id.org/tree/specification/shape-topologies) report. -Every tree:Relation MAY provide a tree:remainingItems. A client MAY use tree:remainingItems to estimate the completeness of the downloaded elements to the end-user. +# Traversing the search tree # {#traversing} -Note: When traversing, a client SHOULD keep a list of already visited pages, as despite this being the TREE spec, circular references and back-links are not explicitly prohibited. +After dereferencing a `tree:Node`, a client MUST extract all (zero or more) `tree:Relation` descriptions from the page. +This can be done by searching for `<> tree:relation ?R` triples. -A tree:import MAY be defined in the tree:Relation instance. When there is a tree:path defined, and when the relation is flagged interesting to follow, the import link needs to be downloaded in order to find the necessary literals to be compared (it is thus already a tree:ConditionalImport. +A client MUST follow the object of the relation’s ?R tree:node ?object triple, unless the client is able to prune them based on the type of the relation, detailled further on. -Note: An example of a tree:import is given [in the repository](https://github.com/TREEcg/specification/blob/master/examples/geospatially-ordered-public-transport/first.ttl#L27). +A client MAY also extract the tree:Relation’s tree:remainingItems if it exists. +If it does, it will be an integer indicating the remaining items to be found after dereferencing the node. -When dereferencing the object of a tree:node triple, the client MUST follow redirects. The URL to be used as the tree:Node URL is the last URL after redirects. +When traversing, a client SHOULD keep also try to detect faulty search trees by keeping a list of already visited pages. -Note: This enables rebalancing search trees. +When dereferencing the object of a tree:node triple, the client MUST follow redirects. -## Fallbacks ## {#fallbacks} +Note: Allowing redirects allows servers to rebalance their search trees over time. -When there is no tree:view triple provided, a client MUST use the tree:Collection from the previous page and still continue extracting members, and extract further relations defined on the current page URL. +A client MAY assume completeness of members intended by the search tree when it derefenced all node links. -When there are no tree:members and/or no tree:Collection defined, then still a tree:Relation can be defined. The tree:path in the tree:Relation then refers to a pattern that can start from every triple in the page. +## Pruning relations ## {#relationsubclasses} -When no tree:path is defined, the tree:value MUST be compared to all members’ triples that *can be compared to* the tree:value as defined by the type of the relation (or when no members or collection are defined, on every triple in the page). -When due to rdfs:range incompatibility, the object cannot be compared, the object will not be considered for comparison. +The object of ?R tree:value ?object MUST be accompanied by a data type when it is a literal value. -Note: This may enable server developers to indicate an index on all literals of the members (e.g., a prefix relation on title, description and body text) without having to indicate all of the alternative paths in the tree:path. +More specific tree:Relation will have a tree:path, indicating the path from the member to the object on which the tree:Relation applies. For the different ways to express or handle a tree:path, we refer to [2.3.1 in the shacl specification](https://www.w3.org/TR/shacl/#x2.3.1-shacl-property-paths). All possible combinations of e.g., shacl:alternativePath, shacl:inversePath or shacl:inLanguage in the SHACL spec can be used. When shacl:alternativePath is used, the order in the list will define the importance of the order when evaluating the tree:Relation. A wildcard in the path is limited to the tree:shape of the tree:Collection. +The result of the evaluation of the tree:path, is the value that must be compared to the tree:value. The target object of a tree:path SHOULD be materialized in the current Node document, but when it is not, the object MAY be considered implicit on the condition both tree:path and tree:member are defined. In contrast to sh:path, a tree:path MAY refer to an implicit property and may not be materialized in the current response. This may break SPARQL processors that did not yet come across the object before in their query plan. However, the tree may still be useful for query processors that, for example, prioritize queries according to the user’s location, and first download nodes that are nearby the user. Therefore, the materialized location of the object is not needed. While not recommended, possible heuristics could try to infer the data, could try to fetch it through another tree:Collection, or retrieve it using URI dereferencing. -## Specific relations ## {#relationsubclasses} +TODO: Note: Need a note on wildcards here + +Deprecated: A tree:import MAY be defined in the tree:Relation instance. When there is a tree:path defined, and when the relation is flagged interesting to follow, the import link needs to be downloaded in order to find the necessary literals to be compared (it is thus already a tree:ConditionalImport. + +Note: Deprecated: an example of a tree:import is given [in the repository](https://github.com/TREEcg/specification/blob/master/examples/geospatially-ordered-public-transport/first.ttl#L27). When the *only* type given for a certain Relation is tree:Relation, then the client must dereference all of the nodes. While this may seem useless, it can be used for the same use case as a hydra:PartialCollectionView. @@ -232,13 +223,9 @@ All properties expect positive integers.
```turtle a tree:Collection ; - dcterms:title "A prototype tree:Collection for Linked OpenStreetMap’s roads"@en ; - tree:view . - - a tree:Node ; - tree:viewDescription . - - a tree:ViewDescription ; + dcterms:title "A prototype tree:Collection for Linked OpenStreetMap’s roads"@en . + a tree:SearchTree ; + tree:search [ a hydra:IriTemplate ; hydra:template "https://tiles.openplanner.team/planet/20201103-095900/{z}/{x}/{y}" ; @@ -259,12 +246,11 @@ All properties expect positive integers. hydra:property tree:zoom; hydra:required true ] - ] . - + ] . ```
-This search form describes a specific search form that uses a quad tree. The zoom level describes the depth, the longitudeTile and latitudeTile describe the x and y index of the fragmentation. (e.g., on zoom level 0, there’s 1 tile, on zoom level 1, there are 4 tiles, etc.). +This search form describes a specific search form that uses a quad tree. The zoom level describes the depth, the longitudeTile and latitudeTile describe the x and y index of the pagination. (e.g., on zoom level 0, there’s 1 tile, on zoom level 1, there are 4 tiles, etc.). ## Searching through a list of objects ordered by time ## {#timesearch} @@ -279,9 +265,6 @@ A tree:path can indicate the time predicate which is intended. tree:view . a tree:Node ; - tree:viewDescription . - - a tree:ViewDescription ; tree:search [ a hydra:IriTemplate ; hydra:template "https://example.org/{generatedAt}" ; @@ -318,10 +301,6 @@ On the resources to import, Memento [[!RFC7089]] controls MAY be provided for hi # Compatibility # {#compatibility} -## DCAT ## {#dcat} - -[[!VOCAB-DCAT-2]] is the standard for Open Data Portals by W3C. In order to find TREE compliant datasets in data portals, there SHOULD be a dcat:endpointDescription from the dcat:DataService to the entrypoint where the tree:Collections and the tree:ViewDescriptions are listed. Furthermore, there SHOULD be a dct:conformsTo this URI: https://w3id.org/tree/specification. - ## Hydra ## {#hydra} A tree:Collection is compatible with the [Hydra Collections specification](https://www.hydra-cg.com/spec/latest/core/#collections). However, instead of hydra:view, we use tree:view and do not link to a hydra:PartialCollectionView but to a tree:Node. diff --git a/03-discovery-specification.bs b/03-discovery-specification.bs index ea0b4cc..eb92eb5 100644 --- a/03-discovery-specification.bs +++ b/03-discovery-specification.bs @@ -1,5 +1,5 @@ # The overview # {#overview} A tree:Collection is a subclass of dcat:Dataset ([[!vocab-dcat-3]]). -The specialization being that it is a DCAT dataset with a collection of _members_. +The specialization being that this particular dataset is a collection of _members_. -A tree:ViewDescription is a subClassOf dcat:DataService and serves a tree:Collection. +A tree:SearchTree is a subClassOf dcat:Distribution. +The specialization being that it uses the main TREE specification to publish a search tree. -A tree:View is a subClassOf dcat:Distribution. +A node from which all other nodes can be found is a `tree:RootNode`, which MAY be explicitely typed as such. -A TREE client MUST be provided with a URL to start from, which we call the entrypoint. -This entrypoint MUST be one of the following: - 1. a `tree:RootNode`, - 2. a `tree:SearchTree` - 3. a `tree:Collection`, or - 4. a `dcat:Catalog` +Note: The `tree:SearchTree` and the `tree:RootNode` MAY be identified by the same IRI when no disambiguation is needed. -# Initializing a client with a url to a... # {#starting-from} +A TREE client MUST be provided with a URL to start from, which we call the _entrypoint_. -## tree:RootNode ## {#rootnode} +# Initializing a client with a url # {#starting-from} -A node from which all members of a collection can be found is a `tree:RootNode`, which MAY be explicitely typed as such. -When the URL given to the TREE client, after all redirects, is used in a triple ex:C1 tree:view <> ., a client MUST assume the URL after redirects is an identifier of a `tree:RootNode` of the collection `ex:C1`. +The goal of the client is to understand what `tree:Collection` it is using, and to find a `tree:RootNode` or search form to start the traversal phase from. -## tree:SearchTree ## {#searchtree} +``` +IN: E: a URL of the entrypoint +OUT: N: tree:RootNode IRI and/or S: search form + ``` -A `tree:SearchTree` is a subClassOf `dcat:Distribution` and distributes one specific `tree:Collection`. -When dereferencing a URL identifying a Search Tree, a server MUST respond with one of the following options: - 1. The `tree:RootNode` of the search tree is returned. On that page, the URI of the `tree:SearchTree` MUST be mentioned in one of the following ways: - * The `tree:RootNode` MAY describe it has a `tree:viewDescription` being the `tree:SearchTree` - * It MAY simply be double typed with the `tree:RootNode` (in which the former chapter is applicable) - 2. A DCAT-based overview of the distribution(s). In this case, the client MUST look for the URL it requested, and check whether there is a property `dcat:accessURL` +The client MUST dereference the URL, which will result in a set of quads. +When the URL given to the TREE client, after all redirects, is used in a triple ex:C tree:view <> ., a client MUST assume the URL after redirects (`E'`) is an identifier of the intended `tree:RootNode` of the collection `ex:C`. +The client MUST check for this `tree:view` property and return the result of the discovery algorithm with `<> → N`. -Through the direct property `tree:rootNode` (subPropertyOf `dcat:accessURL`) one can find the `tree:RootNode`, for which we can then continue with the example above. - -Catalog +If there is no such triple, then the client MUST check whether the URL before redirects (`E`) has been used in one of the following patterns: + * `E tree:view ?N.` where there’s exactly one `?N`, then the algorithm MUST return `?N → N`. + * `E tree:rootNode ?N ; tree:search ?S .` then the algorithm MUST return `?N → N` and `?S → S`. + * `?DS dcat:servesDataset E ; dcat:endpointURL ?U` or `E dcat:endpointURL ?U`, then the algorithm MUST repeat the algorithm with `?U` as the entrypoint. +Note: When data about the dataset, data service or search tree is found, it is a good idea to also pass this on to the client. ## tree:Collection ## {#collection} @@ -85,3 +81,19 @@ Therefore a data publisher SHOULD annotate a tree:Collection instan The tree:shape points to a SHACL description of the shape (sh:NodeShape). Note: the shape can be a blank node, or a named node on which you should follow your nose when it is defined at a different HTTP URL. + +# Context data # {#context} + +Context information is important to understand who the creator of a certain dataset is, when it was last changed, what other datasets it was derived from, etc. + +TODO + +## DCAT and dcterms ## {#context-dcat} + +## Provenance ## {#context-prov} + +## Linked Data Event Streams ## {#context-ldes} + +[LDES](https://w3id.org/ldes/specification) is a way to evolve search trees in a consistent way. It defines every member as immutable, and a collection as append-only. +Therefore, one can make sure to only process each member once. +Extra terms are added, such as the concept of an EventStream, retention policies and a timestampPath. diff --git a/tree.ttl b/tree.ttl index d9ff39c..de2594d 100644 --- a/tree.ttl +++ b/tree.ttl @@ -168,7 +168,6 @@ tree:member a rdf:Property ; tree:search a rdf:Property ; rdfs:label "Search"@en ; rdfs:comment "The Node can be searched for child nodes."@en ; - rdfs:domain tree:Node ; rdfs:range hydra:IriTemplate . tree:shape a rdf:Property ; diff --git a/vocabulary.md b/vocabulary.md index cb413a3..1042590 100644 --- a/vocabulary.md +++ b/vocabulary.md @@ -1,3 +1,21 @@ +# Definitions # {#formalizations} + +A tree:Collection is a set of tree:Members. The set of members MAY be empty. + +A tree:Member is a set of (at least one) quad(s) defined by the member extraction algorithm (next subsection). + +A tree:Node is a dereferenceable resource containing tree:Relations and a subset of () members of the collection. In a tree:Node, both the set of tree:Relations as the subset of members MAY be empty. The same member MAY be contained in multiple nodes. + +A tree:Relation is a function denoting a conditional link to another tree:Node. + +A tree:Node, apart from the root node, has exactly one other tree:Node linking into it through one or more relations. + +Note: The condition of multiple tree:Relations to the same tree:Node MUST be combined with a logical AND. + +A SearchTree is a specific set of interlinked tree:Nodes, that together contain all members in a collection. A specific view will adhere to a certain growth or tree balancing strategy. In one SearchTree, completeness MUST be guaranteed, unless the SearchTree has a retention policy cfr. LDES. + +A tree:search form is an IRI template, that when filled out with the right parameters becomes a tree:Node IRI, or when dereferenced will redirect to a tree:Node from which all members in the collection that adhere to the described comparator can be found. + # Vocabulary # {#vocabulary} **Namespace**: https://w3id.org/tree# @@ -151,6 +169,6 @@ A search form parameter: accompagnied by a tree:path, it indicates ### tree:viewDescription ### {#viewDescription} -Links together a tree:Node with a description that needs to be taken into account +Links together any HTTP response with a view description on which things like retention policies, contact information of a server, etc. can be found. **Domain**: tree:Node From 6497c7ee67bcd86bec48452c679b14b1f622bdbc Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Sun, 1 Sep 2024 10:21:24 +0200 Subject: [PATCH 09/28] Fix LDES reference --- 03-discovery-specification.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/03-discovery-specification.bs b/03-discovery-specification.bs index eb92eb5..49754e7 100644 --- a/03-discovery-specification.bs +++ b/03-discovery-specification.bs @@ -94,6 +94,6 @@ TODO ## Linked Data Event Streams ## {#context-ldes} -[LDES](https://w3id.org/ldes/specification) is a way to evolve search trees in a consistent way. It defines every member as immutable, and a collection as append-only. +LDES (https://w3id.org/ldes/specification) is a way to evolve search trees in a consistent way. It defines every member as immutable, and a collection as append-only. Therefore, one can make sure to only process each member once. Extra terms are added, such as the concept of an EventStream, retention policies and a timestampPath. From e6f558e3fb4122b505792dffea066f045ea75853 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Sun, 1 Sep 2024 20:29:50 +0200 Subject: [PATCH 10/28] Pruning branches --- 01-tree-specification.bs | 45 +++++++++++++++++++++++----------------- vocabulary.md | 2 -- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/01-tree-specification.bs b/01-tree-specification.bs index 2b1f36e..8b920d3 100644 --- a/01-tree-specification.bs +++ b/01-tree-specification.bs @@ -141,12 +141,12 @@ The full algorithm is specificied in the [shape topologies](https://w3id.org/tre After dereferencing a `tree:Node`, a client MUST extract all (zero or more) `tree:Relation` descriptions from the page. This can be done by searching for `<> tree:relation ?R` triples. -A client MUST follow the object of the relation’s ?R tree:node ?object triple, unless the client is able to prune them based on the type of the relation, detailled further on. +A client MUST follow the object of the relation’s ?R tree:node ?object triple, unless the client is able to prune the branch reachable from that node (see further). A client MAY also extract the tree:Relation’s tree:remainingItems if it exists. If it does, it will be an integer indicating the remaining items to be found after dereferencing the node. -When traversing, a client SHOULD keep also try to detect faulty search trees by keeping a list of already visited pages. +When traversing, a client SHOULD detect faulty search trees by keeping a list of already visited pages. When dereferencing the object of a tree:node triple, the client MUST follow redirects. @@ -154,27 +154,35 @@ Note: Allowing redirects allows servers to rebalance their search trees over tim A client MAY assume completeness of members intended by the search tree when it derefenced all node links. -## Pruning relations ## {#relationsubclasses} +# Pruning branches # {#relationsubclasses} -The object of ?R tree:value ?object MUST be accompanied by a data type when it is a literal value. +In search trees, not commonly the `tree:Relation` will be used as the type, but more commonly it will be one of its subclasses. +For partial string matching, `tree:PrefixRelation`, `tree:SubstringRelation`, and `tree:SuffixRelation` exist. +For comparing various datatypes, `tree:GreaterThanRelation`, `tree:GreaterThanOrEqualToRelation`, `tree:LessThanRelation`, `tree:LessThanOrEqualToRelation`, `tree:EqualToRelation`, and `tree:NotEqualToRelation` exist. +Finally, for geospatial trees, `tree:GeospatiallyContainsRelation` exists. -More specific tree:Relation will have a tree:path, indicating the path from the member to the object on which the tree:Relation applies. For the different ways to express or handle a tree:path, we refer to [2.3.1 in the shacl specification](https://www.w3.org/TR/shacl/#x2.3.1-shacl-property-paths). All possible combinations of e.g., shacl:alternativePath, shacl:inversePath or shacl:inLanguage in the SHACL spec can be used. When shacl:alternativePath is used, the order in the list will define the importance of the order when evaluating the tree:Relation. A wildcard in the path is limited to the tree:shape of the tree:Collection. +A client decides, based on their own tasks, what relations are important to implement. +Each relation is a comparator function that helps deciding whether or not the subtree reachable from the `tree:node` link can be pruned. +All relation comparator functions to the same `tree:node` need to be evaluated using a logical AND. +As arguments, it this function takes: + 1. The left-hand: what the members on the linked node will contain w.r.t. the literals reachable from the `tree:path` + 2. The operator: decided by the type of the relation and the datatype or node type of the `tree:value` triple’s object. + 3. The right-hand: the `tree:value` triple’s object. + +If the client comes across a relation subclass it did not code against, it MUST return `true`. + +Subclasses of tree:Relation commonly will use the tree:path to indicate the path from the member to the object on which the tree:Relation applies. For the different ways to express or handle a tree:path, we refer to [2.3.1 in the shacl specification](https://www.w3.org/TR/shacl/#x2.3.1-shacl-property-paths). All possible combinations of e.g., shacl:alternativePath, shacl:inversePath or shacl:inLanguage in the SHACL spec can be used. When shacl:alternativePath is used, the order in the list will define the importance of the order when evaluating the tree:Relation. The result of the evaluation of the tree:path, is the value that must be compared to the tree:value. +When multiple results from the path are found, they need to be interpreted in the function using a logical OR. The target object of a tree:path SHOULD be materialized in the current Node document, but when it is not, the object MAY be considered implicit on the condition both tree:path and tree:member are defined. In contrast to sh:path, a tree:path MAY refer to an implicit property and may not be materialized in the current response. This may break SPARQL processors that did not yet come across the object before in their query plan. However, the tree may still be useful for query processors that, for example, prioritize queries according to the user’s location, and first download nodes that are nearby the user. Therefore, the materialized location of the object is not needed. While not recommended, possible heuristics could try to infer the data, could try to fetch it through another tree:Collection, or retrieve it using URI dereferencing. +Wildcards in the paths (i.e. `sh:zeroOrMorePath`) however do not trigger any further look-ups. -TODO: Note: Need a note on wildcards here - -Deprecated: A tree:import MAY be defined in the tree:Relation instance. When there is a tree:path defined, and when the relation is flagged interesting to follow, the import link needs to be downloaded in order to find the necessary literals to be compared (it is thus already a tree:ConditionalImport. - -Note: Deprecated: an example of a tree:import is given [in the repository](https://github.com/TREEcg/specification/blob/master/examples/geospatially-ordered-public-transport/first.ttl#L27). +When the type given for a certain Relation is tree:Relation, then the client MUST dereference the node if the client needs more results. +While this may seem useless, this more or less has similar semantics to a next page link. -When the *only* type given for a certain Relation is tree:Relation, then the client must dereference all of the nodes. While this may seem useless, it can be used for the same use case as a hydra:PartialCollectionView. - -For other types check the chapter on relation types in the vocabulary [](#Relation). - -### Comparing strings ### {#strings} +## Comparing strings ## {#strings} String values have three specific type of relations: the tree:PrefixRelation, the tree:SubstringRelation and the tree:SuffixRelation. @@ -189,21 +197,20 @@ When no language is set, all strings are compared. Note: If you want to have one resource containing both e and é as a prefix, you will have to create multiple relations to the same tree:Node. -### Comparing named nodes ### {#named-nodes} +## Comparing named nodes ## {#named-nodes} When using comparator relations such as tree:GreaterThanRelation, named nodes must be compared as defined in the [ORDER BY section of the SPARQL specification](https://www.w3.org/TR/sparql11-query/#modOrderBy). -### Comparing geospatial features ### {#geospatial} +## Comparing geospatial features ## {#geospatial} The tree:GeospatiallyContainsRelation is the relation than can be used to express all further members will be contained within a geospatial region defined by the WKT String in the tree:value. When using tree:GeospatiallyContainsRelation, the tree:path MUST refer to a literal containing a WKT string, such as geosparql:asWKT. -### Comparing time literals ### {#time} +## Comparing time literals ## {#time} When using relations such as tree:LessThanRelation or tree:GreaterThanRelation, the time literals need to be compared according to these 3 possible data types: xsd:date, xsd:dateTime or xsd:dateTimeStamp. - # Search forms # {#searching} Searching through a TREE will allow you to immediately jump to the right tree:Node. diff --git a/vocabulary.md b/vocabulary.md index 1042590..b129556 100644 --- a/vocabulary.md +++ b/vocabulary.md @@ -10,8 +10,6 @@ A tree:Relation is a function denoting a conditional link to anothe A tree:Node, apart from the root node, has exactly one other tree:Node linking into it through one or more relations. -Note: The condition of multiple tree:Relations to the same tree:Node MUST be combined with a logical AND. - A SearchTree is a specific set of interlinked tree:Nodes, that together contain all members in a collection. A specific view will adhere to a certain growth or tree balancing strategy. In one SearchTree, completeness MUST be guaranteed, unless the SearchTree has a retention policy cfr. LDES. A tree:search form is an IRI template, that when filled out with the right parameters becomes a tree:Node IRI, or when dereferenced will redirect to a tree:Node from which all members in the collection that adhere to the described comparator can be found. From 75a88817fb82b101c38ac6001b2e60ee31070207 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Sun, 1 Sep 2024 20:30:15 +0200 Subject: [PATCH 11/28] Imports to drafts --- 01-tree-specification.bs | 22 ---------------------- drafts/6-imports.md | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 22 deletions(-) create mode 100644 drafts/6-imports.md diff --git a/01-tree-specification.bs b/01-tree-specification.bs index 8b920d3..f34d11a 100644 --- a/01-tree-specification.bs +++ b/01-tree-specification.bs @@ -179,9 +179,6 @@ The target object of a tree:path SHOULD be materialized in the curr In contrast to sh:path, a tree:path MAY refer to an implicit property and may not be materialized in the current response. This may break SPARQL processors that did not yet come across the object before in their query plan. However, the tree may still be useful for query processors that, for example, prioritize queries according to the user’s location, and first download nodes that are nearby the user. Therefore, the materialized location of the object is not needed. While not recommended, possible heuristics could try to infer the data, could try to fetch it through another tree:Collection, or retrieve it using URI dereferencing. Wildcards in the paths (i.e. `sh:zeroOrMorePath`) however do not trigger any further look-ups. -When the type given for a certain Relation is tree:Relation, then the client MUST dereference the node if the client needs more results. -While this may seem useless, this more or less has similar semantics to a next page link. - ## Comparing strings ## {#strings} String values have three specific type of relations: the tree:PrefixRelation, the tree:SubstringRelation and the tree:SuffixRelation. @@ -287,25 +284,6 @@ A tree:path can indicate the time predicate which is intended. ``` -# Imports # {#imports} - -A tree:import can be defined on multiple levels. When defined as part of a tree:Node, this document always needs to be fetched when processing this Node. -When defined as part of the tree:Relation, one MUST fetch the import when the relation needs to be correctly evaluated (e.g., the resulting page contains elements without materialized WKT strings, which however can be fetched from the import). -When importing a file, no hypermedia relations will be followed from that import in order to get more data. - -A tree:importStream can also be defined for providing a pubsub interface for subscribing to real-time updates. The object SHOULD be a [[!websockets]] or Server-Sent Events ([[!eventsource]]). - -Instead of tree:import, one can also use tree:conditionalImport which links to an object of the type tree:ConditionalImport with these properties: - - * tree:import with a link to the page to import, or a tree:importStream with a pubsub stream to import (optionally) - * tree:path with a property path that indicates the resource that elements in the imported resource contain - -Note: imports are powerful to keep recurring objects in a separate, more cacheable, resource. - -No hypermedia controls in the body MUST be interpreted in the imported resource and the object must be fully contained within that information resource. - -On the resources to import, Memento [[!RFC7089]] controls MAY be provided for historic versions. - # Compatibility # {#compatibility} ## Hydra ## {#hydra} diff --git a/drafts/6-imports.md b/drafts/6-imports.md new file mode 100644 index 0000000..c996b8c --- /dev/null +++ b/drafts/6-imports.md @@ -0,0 +1,18 @@ +# Imports # {#imports} + +A tree:import can be defined on multiple levels. When defined as part of a tree:Node, this document always needs to be fetched when processing this Node. +When defined as part of the tree:Relation, one MUST fetch the import when the relation needs to be correctly evaluated (e.g., the resulting page contains elements without materialized WKT strings, which however can be fetched from the import). +When importing a file, no hypermedia relations will be followed from that import in order to get more data. + +A tree:importStream can also be defined for providing a pubsub interface for subscribing to real-time updates. The object SHOULD be a [[!websockets]] or Server-Sent Events ([[!eventsource]]). + +Instead of tree:import, one can also use tree:conditionalImport which links to an object of the type tree:ConditionalImport with these properties: + + * tree:import with a link to the page to import, or a tree:importStream with a pubsub stream to import (optionally) + * tree:path with a property path that indicates the resource that elements in the imported resource contain + +Note: imports are powerful to keep recurring objects in a separate, more cacheable, resource. + +No hypermedia controls in the body MUST be interpreted in the imported resource and the object must be fully contained within that information resource. + +On the resources to import, Memento [[!RFC7089]] controls MAY be provided for historic versions. \ No newline at end of file From 4d6ecf8d655d8a9e2016c2b484de8963da662e47 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Sun, 1 Sep 2024 20:30:48 +0200 Subject: [PATCH 12/28] Compatibilities to draft --- 01-tree-specification.bs | 114 ------------------------------------ drafts/5-compatibilities.md | 113 +++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 114 deletions(-) create mode 100644 drafts/5-compatibilities.md diff --git a/01-tree-specification.bs b/01-tree-specification.bs index f34d11a..4d158d7 100644 --- a/01-tree-specification.bs +++ b/01-tree-specification.bs @@ -284,118 +284,4 @@ A tree:path can indicate the time predicate which is intended. ``` -# Compatibility # {#compatibility} - -## Hydra ## {#hydra} - -A tree:Collection is compatible with the [Hydra Collections specification](https://www.hydra-cg.com/spec/latest/core/#collections). However, instead of hydra:view, we use tree:view and do not link to a hydra:PartialCollectionView but to a tree:Node. -A hydra:Collection can thus also be extended with a tree:shape and tree:view. -When this is done, also hydra:member can be used instead of tree:member. - -hydra:totalItems can be used to indicate the total amount of elements in the collection. -Hydra paging controls such as hydra:next and hydra:previous are semantically equivalent to a tree:Relation element that only contains a tree:node property. - -## Activity Streams 2.0 ## {#activitystreams} - -A tree:Collection is also compatible with [[!activitystreams-core]]’s specification of [paged collections](https://www.w3.org/TR/activitystreams-core/#collections). -Instead of dcterms:isPartOf, also as:partOf can be used to indicate that the current page is part of the full collection. -While Hydra and TREE link to the members of the collection by using the specific collection as a subject, Activity Streams 2.0 (AS) indicates a member starting from the page URL. -Therefore, when using AS collections, a client implementation should gather the members from the tree:Node or as:CollectionPage instead. - -as:totalItems can be used to indicate the total amount of elements in the collection. - -AS paging controls such as as:nextand as:previous are semantically equivalent to a tree:Relation element that only contains a tree:node property. - -## LDP Containers ## {#ldp} - -In [[!LDP]], the tree:view can be applied on top of the ldp:Container instance. -Members can be found through ldp:contains, and/or through the indirect ldp:membershipResource and ldp:hasMemberRelation or ldp:isMemberOfRelation construct. - -If this container is paged by the [[!ldp-paging]] (chapter 7) spec, then this MUST be ignored. - -If there is an ordering, this MUST be ignored by TREE clients (the relations contain all necessary information for pruning). - -## Shape trees ## {#shapetrees} - -[The Shape Trees specification](https://shapetrees.org/TR/specification/) is specifically built to work within existing ecosystems. -As it was conceived to interoperate with LDP, the term Container in the Shape Trees spec can also be interpreted as a tree:Collection. -Shape Trees can help in the source selection of what specific tree:Collection to pick for your goal, and may add hierarchies to a set of tree:Collections. -A client MAY infer a tree:shape of the collection through the st:validatedBy property of the Shapes Tree. - -An example of a collection using Shape Tree terms. In this example a sensor with some observations is validated by using a [Shape Expressions](http://shex.io/shex-semantics/) (ShEx) file. - -
- ```turtle - @prefix sosa: . - @prefix om: . - @prefix ldp: . - - <2021.ttl#Collection> a ldp:Container; - st:validatedBy ; - tree:member , . - - - a sosa:Sensor; - sosa:madeObservation - , - ; - sosa:observes om:Temperature . - - - a sosa:Observation; - sosa:observedProperty om:Temperature; - sosa:madeBySensor ; - sosa:hasResult ; - sosa:resultTime "2020-08-25T07:05:31Z"^^xsd:dateTime . - - a om:Measure; - om:hasValue "22"^^xsd:float; - om:hasUnit om:degreeCelsius . - - - a sosa:Observation; - sosa:observedProperty om:Temperature; - sosa:madeBySensor ; - sosa:hasResult ; - sosa:resultTime "2020-08-25T07:05:32Z"^^xsd:dateTime . - - a om:Measure; - om:hasValue "22"^^xsd:float; - om:hasUnit om:degreeCelsius . - - - a sosa:Sensor; - sosa:observes om:Temperature . - ``` - - And its corresponding ShEx file (called Sensor.shex) - - ```shex - PREFIX sosa: - PREFIX xsd: - PREFIX om: - PREFIX rdfs: - - <#Sensor> { - a [sosa:Sensor] ; - sosa:observes [om:Temperature] ; - sosa:madeObservation @<#TemperatureObservation> * - } - - <#TemperatureObservation> { - a [sosa:Observation] ; - sosa:resultTime xsd:dateTime ; - sosa:madeBySensor @<#Sensor> ? ; - sosa:observedProperty [om:Temperature]; - sosa:hasResult @<#TemperatureResult> - } - - <#TemperatureResult> { - a [om:Measure]; - om:hasValue xsd:float ; - om:hasUnit [om:degreeCelsius] - } - ``` -
-
path: vocabulary.md
diff --git a/drafts/5-compatibilities.md b/drafts/5-compatibilities.md new file mode 100644 index 0000000..658c43d --- /dev/null +++ b/drafts/5-compatibilities.md @@ -0,0 +1,113 @@ +# Compatibility # {#compatibility} + +## Hydra ## {#hydra} + +A tree:Collection is compatible with the [Hydra Collections specification](https://www.hydra-cg.com/spec/latest/core/#collections). However, instead of hydra:view, we use tree:view and do not link to a hydra:PartialCollectionView but to a tree:Node. +A hydra:Collection can thus also be extended with a tree:shape and tree:view. +When this is done, also hydra:member can be used instead of tree:member. + +hydra:totalItems can be used to indicate the total amount of elements in the collection. +Hydra paging controls such as hydra:next and hydra:previous are semantically equivalent to a tree:Relation element that only contains a tree:node property. + +## Activity Streams 2.0 ## {#activitystreams} + +A tree:Collection is also compatible with [[!activitystreams-core]]’s specification of [paged collections](https://www.w3.org/TR/activitystreams-core/#collections). +Instead of dcterms:isPartOf, also as:partOf can be used to indicate that the current page is part of the full collection. +While Hydra and TREE link to the members of the collection by using the specific collection as a subject, Activity Streams 2.0 (AS) indicates a member starting from the page URL. +Therefore, when using AS collections, a client implementation should gather the members from the tree:Node or as:CollectionPage instead. + +as:totalItems can be used to indicate the total amount of elements in the collection. + +AS paging controls such as as:nextand as:previous are semantically equivalent to a tree:Relation element that only contains a tree:node property. + +## LDP Containers ## {#ldp} + +In [[!LDP]], the tree:view can be applied on top of the ldp:Container instance. +Members can be found through ldp:contains, and/or through the indirect ldp:membershipResource and ldp:hasMemberRelation or ldp:isMemberOfRelation construct. + +If this container is paged by the [[!ldp-paging]] (chapter 7) spec, then this MUST be ignored. + +If there is an ordering, this MUST be ignored by TREE clients (the relations contain all necessary information for pruning). + +## Shape trees ## {#shapetrees} + +[The Shape Trees specification](https://shapetrees.org/TR/specification/) is specifically built to work within existing ecosystems. +As it was conceived to interoperate with LDP, the term Container in the Shape Trees spec can also be interpreted as a tree:Collection. +Shape Trees can help in the source selection of what specific tree:Collection to pick for your goal, and may add hierarchies to a set of tree:Collections. +A client MAY infer a tree:shape of the collection through the st:validatedBy property of the Shapes Tree. + +An example of a collection using Shape Tree terms. In this example a sensor with some observations is validated by using a [Shape Expressions](http://shex.io/shex-semantics/) (ShEx) file. + +
+ ```turtle + @prefix sosa: . + @prefix om: . + @prefix ldp: . + + <2021.ttl#Collection> a ldp:Container; + st:validatedBy ; + tree:member , . + + + a sosa:Sensor; + sosa:madeObservation + , + ; + sosa:observes om:Temperature . + + + a sosa:Observation; + sosa:observedProperty om:Temperature; + sosa:madeBySensor ; + sosa:hasResult ; + sosa:resultTime "2020-08-25T07:05:31Z"^^xsd:dateTime . + + a om:Measure; + om:hasValue "22"^^xsd:float; + om:hasUnit om:degreeCelsius . + + + a sosa:Observation; + sosa:observedProperty om:Temperature; + sosa:madeBySensor ; + sosa:hasResult ; + sosa:resultTime "2020-08-25T07:05:32Z"^^xsd:dateTime . + + a om:Measure; + om:hasValue "22"^^xsd:float; + om:hasUnit om:degreeCelsius . + + + a sosa:Sensor; + sosa:observes om:Temperature . + ``` + + And its corresponding ShEx file (called Sensor.shex) + + ```shex + PREFIX sosa: + PREFIX xsd: + PREFIX om: + PREFIX rdfs: + + <#Sensor> { + a [sosa:Sensor] ; + sosa:observes [om:Temperature] ; + sosa:madeObservation @<#TemperatureObservation> * + } + + <#TemperatureObservation> { + a [sosa:Observation] ; + sosa:resultTime xsd:dateTime ; + sosa:madeBySensor @<#Sensor> ? ; + sosa:observedProperty [om:Temperature]; + sosa:hasResult @<#TemperatureResult> + } + + <#TemperatureResult> { + a [om:Measure]; + om:hasValue xsd:float ; + om:hasUnit [om:degreeCelsius] + } + ``` +
From 90bdac8ba3721dcf722ebef8ce617df553268592 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Mon, 2 Sep 2024 08:58:11 +0200 Subject: [PATCH 13/28] Remove SearchTree from the main spec --- 01-tree-specification.bs | 30 ++++++++++++++++++++++++------ vocabulary.md | 20 -------------------- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/01-tree-specification.bs b/01-tree-specification.bs index 4d158d7..891ab14 100644 --- a/01-tree-specification.bs +++ b/01-tree-specification.bs @@ -27,13 +27,12 @@ The TREE specification introduces these core concepts: * a tree:Node: is a page in the search tree - `tree:relation` points at relations to other node - a tree:search describes a search form that allows an agent to jump to a specific tree:Node in the (sub)tree from here. - - tree:viewDescription links a description of (such as a tree:SearchTree, a `dcat:Distribution`, a `dcat:DataService`) + - tree:viewDescription links to a description (MAY be partial and MAY be shared with other trees) of this view that is important to take into account for the current traversal algorithm (such as a `dcat:Distribution` or a `dcat:DataService`) * a tree:Relation is a relation from one node to another. An extension of this class indicates a specific type of relation (e.g., a tree:GreaterThanRelation). A relation typically has these properties: - a tree:node the URL of the other node - a tree:path indicating to which of the members' properties this relation applies - a tree:value indicating a value constraint on the members' values - a tree:remainingItems defining how many members can be reached when following this relation - * a tree:SearchTree is this collection of nodes. The SearchTree can be double typed with the root `tree:Node`, but can also be linked through the property `tree:viewDescription`. A simple collection can be created as illustrated in the following example: @@ -55,7 +54,7 @@ A simple collection can be created as illustrated in the following example: From the moment this collection of members grows too large for one page, -a pagination needs to be created in which an initial set of members can be found through the rootnode, +a pagination needs to be created in which an initial set of members can be found through the first `tree:Node`, and more members can be found by interpreting the TREE hypermedia controls. This is illustrated in the next example: @@ -75,7 +74,7 @@ This is illustrated in the next example: tree:value 3; tree:path ex:value . - ex:R1 a tree:LessThanRelation ; # This is very useful for a client that is looking for a value 10 or greater + ex:R1 a tree:LessThanRelation ; # This is useful for a client that is looking for a value 10 or greater tree:node ex:Node3 ; tree:value 10; tree:remainingItems 7 ; @@ -97,6 +96,25 @@ This is illustrated in the next example: ``` +# Definitions # {#formalizations} + +A tree:Collection is a set of tree:Members. +The set of members MAY be empty. + +A tree:Member is a set of (at least one) quad(s) defined by the member extraction algorithm (see further). + +A tree:Node is a dereferenceable resource containing tree:Relations and a subset of () members of the collection. In a tree:Node, both the set of tree:Relations as the subset of members MAY be empty. The same member MAY be contained in multiple nodes. + +A tree:Relation is a function denoting a conditional link to another tree:Node. + +A tree:Node is part of a search tree, and apart from the root node, it has exactly one other tree:Node of the search tree linking into it through one or more relations. + +A tree:search form is an IRI template, that when filled out with the right parameters becomes a tree:Node IRI, or when dereferenced will redirect to a tree:Node from which all members in the collection that adhere to the described comparator can be found. + +A search tree is a set of interlinked tree:Nodes. +It will adhere to a certain growth or tree balancing strategy. +In one tree, completeness MUST be guaranteed, unless indicated otherwise using a retention policy (as is possible in LDES). + # Initialization # {#init} A client SHOULD be initiated using a URL. @@ -108,7 +126,7 @@ Note: Dereferencing in this specification also means parsing the RDF triples or If there is no such triple, then the client MUST check whether the URL before redirects (`E`) has been used in a pattern ` tree:view ?N.` where there’s exactly one `?N`, then the algorithm MUST return `?N` as the rootnode and `E` as the collection. The client then MUST dereference the identified rootnode (if it did not do that already) and merge those quads with the already found quads. -It now MUST look for a potential search forms that MAY be linked, either i) on top of the rootnode, either ii) on top of the entity linked through `tree:viewDescription`, or iii) on the `tree:SearchTree` using `tree:search`. +It now MUST look for a potential search forms that MAY be linked, either i) on top of the rootnode, or ii) on top of the entity linked through `tree:viewDescription`, using `tree:search`. The resulting collection IRI `C`, the rootnode IRI `R`, list of already visited pages `H` (and optionally their time to live), current quads `Q` and search forms `S`. @@ -228,7 +246,7 @@ All properties expect positive integers. ```turtle a tree:Collection ; dcterms:title "A prototype tree:Collection for Linked OpenStreetMap’s roads"@en . - a tree:SearchTree ; + a tree:Node ; tree:search [ a hydra:IriTemplate ; diff --git a/vocabulary.md b/vocabulary.md index b129556..5fcb739 100644 --- a/vocabulary.md +++ b/vocabulary.md @@ -1,19 +1,3 @@ -# Definitions # {#formalizations} - -A tree:Collection is a set of tree:Members. The set of members MAY be empty. - -A tree:Member is a set of (at least one) quad(s) defined by the member extraction algorithm (next subsection). - -A tree:Node is a dereferenceable resource containing tree:Relations and a subset of () members of the collection. In a tree:Node, both the set of tree:Relations as the subset of members MAY be empty. The same member MAY be contained in multiple nodes. - -A tree:Relation is a function denoting a conditional link to another tree:Node. - -A tree:Node, apart from the root node, has exactly one other tree:Node linking into it through one or more relations. - -A SearchTree is a specific set of interlinked tree:Nodes, that together contain all members in a collection. A specific view will adhere to a certain growth or tree balancing strategy. In one SearchTree, completeness MUST be guaranteed, unless the SearchTree has a retention policy cfr. LDES. - -A tree:search form is an IRI template, that when filled out with the right parameters becomes a tree:Node IRI, or when dereferenced will redirect to a tree:Node from which all members in the collection that adhere to the described comparator can be found. - # Vocabulary # {#vocabulary} **Namespace**: https://w3id.org/tree# @@ -38,10 +22,6 @@ A collection has members that may adhere to a certain shape. A tree:Node is a node that may contain links to other dereferenceable resources that lead to a full overview of a tree:Collection. -### tree:RootNode ### {#RootNode} - -### tree:SearchTree ### {#SearchTree} - ### tree:Relation ### {#Relation} An entity that describes a relation between two tree:Nodes. From 8d0c021204a47c6cf8387b9f083efc28d62cf944 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Thu, 12 Sep 2024 16:54:50 +0200 Subject: [PATCH 14/28] Traversal proofreading --- 01-tree-specification.bs | 160 ++++++++++++++++++++++----------------- 1 file changed, 92 insertions(+), 68 deletions(-) diff --git a/01-tree-specification.bs b/01-tree-specification.bs index 891ab14..53f55af 100644 --- a/01-tree-specification.bs +++ b/01-tree-specification.bs @@ -20,19 +20,19 @@ Abstract: An overview of the TREE specification with the TREE collection, a reference to the first focus node of its members, and the relations to other nodes from the current node.
The TREE specification introduces these core concepts: - * a tree:Collection is a set of members. It typically has these properties when described in a node: - - tree:member points at the first focus node from which to retrieve and extract all quads of a member - - tree:view points to the tree:Node you’re currently visiting - - tree:shape indicates the [[!SHACL]] shape (exactly one) to which each member in the collection adheres - * a tree:Node: is a page in the search tree + * a `tree:Collection` is a set of members. It typically has these properties when described in a node: + - `tree:member` points at the first focus node from which to retrieve and extract all quads of a member + - `tree:view` points to the `tree:Node` you are currently visiting + - `tree:shape` indicates the [[!SHACL]] shape (exactly one) to which each member in the collection adheres + * a `tree:Node`: is a page in the search tree - `tree:relation` points at relations to other node - - a tree:search describes a search form that allows an agent to jump to a specific tree:Node in the (sub)tree from here. - - tree:viewDescription links to a description (MAY be partial and MAY be shared with other trees) of this view that is important to take into account for the current traversal algorithm (such as a `dcat:Distribution` or a `dcat:DataService`) - * a tree:Relation is a relation from one node to another. An extension of this class indicates a specific type of relation (e.g., a tree:GreaterThanRelation). A relation typically has these properties: - - a tree:node the URL of the other node - - a tree:path indicating to which of the members' properties this relation applies - - a tree:value indicating a value constraint on the members' values - - a tree:remainingItems defining how many members can be reached when following this relation + - a `tree:search` describes a search form that allows an agent to jump to a specific `tree:Node` in the (sub)tree from this node + - `tree:viewDescription` points to an entity with a reusable piece of information relevant to the full search tree. Multiple descriptions MUST be combined. + * a `tree:Relation` is a relation from one node to another. An extension of this class indicates a specific type of relation (e.g., a `tree:GreaterThanRelation`). A relation typically has these properties: + - a `tree:node` the URL of the other node + - a `tree:path` indicating to which of the members' properties this relation applies + - a `tree:value` indicating a value constraint on the members' values + - a `tree:remainingItems` defining how many members can be reached when following this relation A simple collection can be created as illustrated in the following example:
@@ -98,28 +98,28 @@ This is illustrated in the next example: # Definitions # {#formalizations} -A tree:Collection is a set of tree:Members. +A `tree:Collection` is a set of `tree:Member`s. The set of members MAY be empty. -A tree:Member is a set of (at least one) quad(s) defined by the member extraction algorithm (see further). +A `tree:Member` is a set of (at least one) quad(s) defined by the member extraction algorithm (see further). -A tree:Node is a dereferenceable resource containing tree:Relations and a subset of () members of the collection. In a tree:Node, both the set of tree:Relations as the subset of members MAY be empty. The same member MAY be contained in multiple nodes. +A `tree:Node` is a dereferenceable resource containing `tree:Relation`s and a subset of (`⊆`) members of the collection. In a `tree:Node`, both the set of `tree:Relation`s as the subset of members MAY be empty. The same member MAY be contained in multiple nodes. -A tree:Relation is a function denoting a conditional link to another tree:Node. +A `tree:Relation` is a function denoting a conditional link to another `tree:Node`. -A tree:Node is part of a search tree, and apart from the root node, it has exactly one other tree:Node of the search tree linking into it through one or more relations. +A `tree:Node` is part of a search tree, and apart from the root node, it has exactly one other `tree:Node` of the search tree linking into it through one or more relations. -A tree:search form is an IRI template, that when filled out with the right parameters becomes a tree:Node IRI, or when dereferenced will redirect to a tree:Node from which all members in the collection that adhere to the described comparator can be found. +A `tree:search` form is an IRI template, that when filled out with the right parameters becomes a `tree:Node` IRI, or when dereferenced will redirect to a `tree:Node` from which all members in the collection that adhere to the described comparator can be found. -A search tree is a set of interlinked tree:Nodes. +A search tree is a set of interlinked `tree:Node`s. It will adhere to a certain growth or tree balancing strategy. In one tree, completeness MUST be guaranteed, unless indicated otherwise using a retention policy (as is possible in LDES). # Initialization # {#init} -A client SHOULD be initiated using a URL. +A client SHOULD be initiated using a URL. The client MUST dereference the URL, which will result in a set of [[!rdf-concepts]] triples or quads. -When the URL after all redirects, is used in a triple ?c tree:view <> ., a client MUST assume the URL after redirects is an identifier of the intended root node of the collection in `?c`. +When the URL after all redirects, is used in a triple `?c tree:view <> .`, a client MUST assume the URL after redirects is an identifier of the intended root node of the collection in `?c`. Note: Dereferencing in this specification also means parsing the RDF triples or quads from the HTTP response. TREE does not limit the content-types that can be used to represent RDF triples. Client developers should do a best-effort for their community. @@ -128,8 +128,6 @@ If there is no such triple, then the client MUST check whether the URL before re The client then MUST dereference the identified rootnode (if it did not do that already) and merge those quads with the already found quads. It now MUST look for a potential search forms that MAY be linked, either i) on top of the rootnode, or ii) on top of the entity linked through `tree:viewDescription`, using `tree:search`. -The resulting collection IRI `C`, the rootnode IRI `R`, list of already visited pages `H` (and optionally their time to live), current quads `Q` and search forms `S`. - In case it is not done using an unambiguous URL, clients MAY implement the report on [Discovery and Context Information (work in progress)](https://w3id.org/tree/specification/discovery). This report also explains how clients MAY implement support for extracting context information such as provenance, contact points, etc. @@ -137,36 +135,32 @@ Note: Having an identifier for the collection has become mandatory: without it y # The member extraction algorithm # {#member-extraction-algorithm} -TODO: review motivation - -
-Thanks to the member extraction algorithm, a data publisher can define their members in different ways: - 1. As in the examples above: all quads with the object of the tree:member quads as a subject (and recursively the quads of their blank nodes) are by default included (see also [[!CBD]]), except when they would explicitely not be included in case 3, when the shape would be closed. +The member extraction algorithm allows a data publisher to define their members in different ways: + 1. As in the examples above: all quads with the object of the `tree:member` quads as a subject (and recursively the quads of their blank nodes) are by default included (see also [[!CBD]]), except when they would explicitely not be included in case 3, when the shape would be closed. 2. Out of band / in band: - when no quads of a member have been found, the member will be dereferenced. This allows to publish the member on a separate page. - part of the member can be maintained elsewhere when a shape is defined (see 3) - 3. By defining a more complex shape with tree:shape, also nested entities can be included in the member - 4. By putting the triples in a named graph of the object of tree:member, all these triples will be matched. -
+ 3. By defining a more complex shape with `tree:shape`, also nested entities can be included in the member + 4. By putting the triples in a named graph of the object of `tree:member`, all these triples will be matched. -Depending on the goals of the client, it MAY implement the member extraction algorithm. -It MUST implement the algorithm in case the goal is to find the complete and finite set of quads that are part of a member as intended by the data publisher. -The method used withun TREE is combination of Concise Bounded Descriptions, named graphs and the topology of a shape (deducted from the `tree:shape`). +Depending on the goals of the client, it MAY implement the member extraction algorithm to fetch all triples about the entity as intended by the server. +The method used withun TREE is combination of Concise Bounded Descriptions [[!CBD]], named graphs and the topology of a shape (deducted from the `tree:shape`). The full algorithm is specificied in the [shape topologies](https://w3id.org/tree/specification/shape-topologies) report. # Traversing the search tree # {#traversing} After dereferencing a `tree:Node`, a client MUST extract all (zero or more) `tree:Relation` descriptions from the page. This can be done by searching for `<> tree:relation ?R` triples. +A client MAY assume completeness of relations mentioned on this page. -A client MUST follow the object of the relation’s ?R tree:node ?object triple, unless the client is able to prune the branch reachable from that node (see further). +A client MUST follow the object of the relation’s `?R tree:node ?object` triple, unless the client is able to prune the branch reachable from that node (see further). -A client MAY also extract the tree:Relation’s tree:remainingItems if it exists. +A client MAY also extract the `tree:Relation`’s `tree:remainingItems` if it exists. If it does, it will be an integer indicating the remaining items to be found after dereferencing the node. When traversing, a client SHOULD detect faulty search trees by keeping a list of already visited pages. -When dereferencing the object of a tree:node triple, the client MUST follow redirects. +When dereferencing the object of a `tree:node` triple, the client MUST follow redirects. Note: Allowing redirects allows servers to rebalance their search trees over time. @@ -174,71 +168,101 @@ A client MAY assume completeness of members intended by the search tree when it # Pruning branches # {#relationsubclasses} -In search trees, not commonly the `tree:Relation` will be used as the type, but more commonly it will be one of its subclasses. +In search trees, a `tree:Relation` will likely be typed using one of its subclasses. For partial string matching, `tree:PrefixRelation`, `tree:SubstringRelation`, and `tree:SuffixRelation` exist. For comparing various datatypes, `tree:GreaterThanRelation`, `tree:GreaterThanOrEqualToRelation`, `tree:LessThanRelation`, `tree:LessThanOrEqualToRelation`, `tree:EqualToRelation`, and `tree:NotEqualToRelation` exist. Finally, for geospatial trees, `tree:GeospatiallyContainsRelation` exists. -A client decides, based on their own tasks, what relations are important to implement. +A client decides, based on their own tasks, what type of relations are important to implement. Each relation is a comparator function that helps deciding whether or not the subtree reachable from the `tree:node` link can be pruned. -All relation comparator functions to the same `tree:node` need to be evaluated using a logical AND. -As arguments, it this function takes: - 1. The left-hand: what the members on the linked node will contain w.r.t. the literals reachable from the `tree:path` +All relations to the same `tree:node` MUST be combined using a logical AND. +The client SHOULD assume the subtree contains __all remaining members__ of the collection that match this comparator and the comparators that lead to the current node. + +One relation can be interpreted as a comparator as follows: + 1. The left-hand: what the members in the substree reachable from the linked node will contain w.r.t. the objects reachable from the `tree:path`. 2. The operator: decided by the type of the relation and the datatype or node type of the `tree:value` triple’s object. 3. The right-hand: the `tree:value` triple’s object. -If the client comes across a relation subclass it did not code against, it MUST return `true`. +
+```turtle +<> tree:relation [ + a tree:GreaterThanRelation ; + tree:node ex:Node2 ; + tree:path dct:created ; + tree:value "2024-12-16T12:00:00Z"^^xsd:dateTime + ],[ + a tree:SubstringRelation ; + tree:node ex:Node2 ; + tree:path dct:title ; + tree:value "osa" + ] . +``` +
+ +In the example above the substree reachable from `ex:Node2` will contain members that are both created later in time than the given timestamp _and_ will have the provided substring in the title. +The client SHOULD prune the subtree reachable from `ex:Node` if it is specifically not looking for members with the given substring, _or_ when it is not interested in members created later in time than the given timestamp. +Alternatively, it MAY score the relation based on the likelihood of returning useful results and created a priority queue that is processed until a top K of results have been found. +It MAY also specifically choose to follow this link, and prune all others in the current node, if it is _only_ interested in members with the given substring _and_ created later in time than the given timestamp. + +If the client comes across a relation subclass it did not code against or did not formulate a condition against, it MUST ignore this relation when assessing whether pruning is possible, but it will not be able to assume completeness. +I.e., in the example above, when the client is specifically not interested in members created later than the given creation time, but does not understand the SubstringRelation, the client MUST still prune the relation. +If however it is only interested in members created later than the given creation time, it cannot prune all other relations. -Subclasses of tree:Relation commonly will use the tree:path to indicate the path from the member to the object on which the tree:Relation applies. For the different ways to express or handle a tree:path, we refer to [2.3.1 in the shacl specification](https://www.w3.org/TR/shacl/#x2.3.1-shacl-property-paths). All possible combinations of e.g., shacl:alternativePath, shacl:inversePath or shacl:inLanguage in the SHACL spec can be used. When shacl:alternativePath is used, the order in the list will define the importance of the order when evaluating the tree:Relation. -The result of the evaluation of the tree:path, is the value that must be compared to the tree:value. -When multiple results from the path are found, they need to be interpreted in the function using a logical OR. +While each type of relation can decide on their own properties, +relations will often use the `tree:path` to indicate the path from the member to the object on which the `tree:Relation` applies. +For the different ways to express or handle a `tree:path`, we refer to [2.3.1 in the shacl specification](https://www.w3.org/TR/shacl/#x2.3.1-shacl-property-paths). +All possible combinations of e.g., `sh:alternativePath` or `sh:inversePath` in the SHACL spec can be used. +The resulting values of the evaluation of the `tree:path`, are the values that must be compared to the `tree:value` object. +When multiple results from the path are found, they need to be interpreted as a logical OR: at least one of these values will fulfill the comparator. -The target object of a tree:path SHOULD be materialized in the current Node document, but when it is not, the object MAY be considered implicit on the condition both tree:path and tree:member are defined. -In contrast to sh:path, a tree:path MAY refer to an implicit property and may not be materialized in the current response. This may break SPARQL processors that did not yet come across the object before in their query plan. However, the tree may still be useful for query processors that, for example, prioritize queries according to the user’s location, and first download nodes that are nearby the user. Therefore, the materialized location of the object is not needed. While not recommended, possible heuristics could try to infer the data, could try to fetch it through another tree:Collection, or retrieve it using URI dereferencing. -Wildcards in the paths (i.e. `sh:zeroOrMorePath`) however do not trigger any further look-ups. +A client, in case it wants to process relations that use the `tree:path` property, MUST implement a matching algorithm to check whether the relation is relevant. +I.e., a `tree:path` on `(rdfs:label [sh:alternativePath rdfs:comment ] )` will be useful when the client is tasked to filter on `rdfs:comment`. + +Note: A server MAY link the `tree:path` to a property that is not materialized in the current response. For the client, if it also needs those triples, we assume in this spec that the client has another way of retrieving those, or already retrieved them from another source. ## Comparing strings ## {#strings} -String values have three specific type of relations: the tree:PrefixRelation, the tree:SubstringRelation and the tree:SuffixRelation. +String values have three specific type of relations: the `tree:PrefixRelation`, the `tree:SubstringRelation` and the `tree:SuffixRelation`. + +Issue: Proposal would be to include that the string comparison should be done using [unicode caseless canonical equivalence](https://icu4c-demos.unicode.org/icu-bin/scompare#a_Equiv_Caseless). However, the fact we would do this in a caseless manner is not consistent with the current spec further on case sensitive unicode ordering and the note on the multiple relations. -Note: We experimented with server-chosen locales such that ça suffit can also be found when following a tree:PrefixRelation with a tree:value "c" (which at this moment is not supported). That would require an understanding of locales, and [browser/JavaScript support for locales is too low to be useful at this point](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_identification_and_negotiation). +Issue: We experimented with server-chosen locales such that `ça suffit` can also be found when following a `tree:PrefixRelation` with a `tree:value "c"` (which at this moment is not supported). That would require an understanding of locales, and [browser/JavaScript support for locales is too low to be useful at this point](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_identification_and_negotiation). -Also the comparator relations such as tree:GreaterThanRelation can be used. +Also the comparator relations such as `tree:GreaterThanRelation` can be used. The strings MUST then be compared according to *case sensitive unicode ordering*. -When a tree:path is defined, mind that you also may have to check the language of the element using the property shacl:inLanguage -More languages MAY be set. -When no language is set, all strings are compared. +When a language is set on the `tree:value`, the relation only refers to these language strings. If no language is indicated, it refers to all (including those without). -Note: If you want to have one resource containing both e and é as a prefix, you will have to create multiple relations to the same tree:Node. +Note: If you want to have one resource containing both `e` and `é` as a prefix, you will have to create multiple relations to the same `tree:Node`. ## Comparing named nodes ## {#named-nodes} -When using comparator relations such as tree:GreaterThanRelation, named nodes must be compared as defined in the [ORDER BY section of the SPARQL specification](https://www.w3.org/TR/sparql11-query/#modOrderBy). +When using comparator relations such as `tree:GreaterThanRelation`, named nodes MUST be compared as defined in the [ORDER BY section of the SPARQL specification](https://www.w3.org/TR/sparql11-query/#modOrderBy). ## Comparing geospatial features ## {#geospatial} -The tree:GeospatiallyContainsRelation is the relation than can be used to express all further members will be contained within a geospatial region defined by the WKT String in the tree:value. +The `tree:GeospatiallyContainsRelation` is the relation that can be used to express all further members will be contained within a geospatial region defined by the WKT String in the `tree:value`. +The client MUST consider the relation when it overlaps with the region of interest. -When using tree:GeospatiallyContainsRelation, the tree:path MUST refer to a literal containing a WKT string, such as geosparql:asWKT. +When using `tree:GeospatiallyContainsRelation`, the `tree:path` MUST refer to a literal containing a WKT string, such as `geosparql:asWKT`. ## Comparing time literals ## {#time} -When using relations such as tree:LessThanRelation or tree:GreaterThanRelation, the time literals need to be compared according to these 3 possible data types: xsd:date, xsd:dateTime or xsd:dateTimeStamp. +When using relations such as `tree:LessThanRelation` or `tree:GreaterThanRelation`, the time literals MUST to be compared according to these 3 possible data types: `xsd:date`, `xsd:dateTime` or `xsd:dateTimeStamp`. # Search forms # {#searching} -Searching through a TREE will allow you to immediately jump to the right tree:Node. +Searching through a TREE will allow you to immediately jump to the right `tree:Node`. TREE relies on the [Hydra search specification](http://www.hydra-cg.com/spec/latest/core/#hydra:search) for its search forms. -It does however extend Hydra with specific search properties (hydra:IriTemplate) for different types of search forms, and searches starting from a tree:ViewDescription, to which the search form is linked with tree:search. +It does however extend Hydra with specific search properties (`hydra:IriTemplate`) for different types of search forms, and searches starting from a `tree:ViewDescription`, to which the search form is linked with `tree:search`. The behaviour of the search form fully depends on the specific property, for which TREE introduces a couple of specific properties: ## Geospatial XYZ tiles search form ## {#xyztiles} Three properties allow to specify a geospatial XYZ tiles template (also known as slippy maps). - 1. tree:longitudeTile describes the X value - 2. tree:latitudeTile descrbes the Y value - 3. tree:zoom describes the zoom level + 1. `tree:longitudeTile` describes the X value + 2. `tree:latitudeTile` descrbes the Y value + 3. `tree:zoom` describes the zoom level All properties expect positive integers. @@ -268,7 +292,7 @@ All properties expect positive integers. hydra:property tree:zoom; hydra:required true ] - ] . + ] . ``` @@ -276,9 +300,9 @@ This search form describes a specific search form that uses a quad tree. The zoo ## Searching through a list of objects ordered by time ## {#timesearch} -Same as the previous example but with the predicate tree:timeQuery expecting an xsd:dateTime. +Same as the previous example but with the predicate `tree:timeQuery` expecting an `xsd:dateTime`. This time however, when the page itself does not exist, a redirect is doing to happen to the page containing the timestamp. -A tree:path can indicate the time predicate which is intended. +A `tree:path` can indicate the time predicate which is intended.
```turtle From edba4085ffdd194dc2a24480838e33e32bf9f6ff Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Thu, 19 Sep 2024 14:35:59 +0200 Subject: [PATCH 15/28] clear out time and substring relation --- 01-tree-specification.bs | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/01-tree-specification.bs b/01-tree-specification.bs index 53f55af..f40ce94 100644 --- a/01-tree-specification.bs +++ b/01-tree-specification.bs @@ -151,7 +151,6 @@ The full algorithm is specificied in the [shape topologies](https://w3id.org/tre After dereferencing a `tree:Node`, a client MUST extract all (zero or more) `tree:Relation` descriptions from the page. This can be done by searching for `<> tree:relation ?R` triples. -A client MAY assume completeness of relations mentioned on this page. A client MUST follow the object of the relation’s `?R tree:node ?object` triple, unless the client is able to prune the branch reachable from that node (see further). @@ -176,7 +175,6 @@ Finally, for geospatial trees, `tree:GeospatiallyContainsRelation` exists. A client decides, based on their own tasks, what type of relations are important to implement. Each relation is a comparator function that helps deciding whether or not the subtree reachable from the `tree:node` link can be pruned. All relations to the same `tree:node` MUST be combined using a logical AND. -The client SHOULD assume the subtree contains __all remaining members__ of the collection that match this comparator and the comparators that lead to the current node. One relation can be interpreted as a comparator as follows: 1. The left-hand: what the members in the substree reachable from the linked node will contain w.r.t. the objects reachable from the `tree:path`. @@ -199,14 +197,11 @@ One relation can be interpreted as a comparator as follows: ```
-In the example above the substree reachable from `ex:Node2` will contain members that are both created later in time than the given timestamp _and_ will have the provided substring in the title. +In the example above the subtree reachable from `ex:Node2` will contain members that are both created later in time than the given timestamp _and_ will have the provided substring in the title. The client SHOULD prune the subtree reachable from `ex:Node` if it is specifically not looking for members with the given substring, _or_ when it is not interested in members created later in time than the given timestamp. Alternatively, it MAY score the relation based on the likelihood of returning useful results and created a priority queue that is processed until a top K of results have been found. -It MAY also specifically choose to follow this link, and prune all others in the current node, if it is _only_ interested in members with the given substring _and_ created later in time than the given timestamp. -If the client comes across a relation subclass it did not code against or did not formulate a condition against, it MUST ignore this relation when assessing whether pruning is possible, but it will not be able to assume completeness. -I.e., in the example above, when the client is specifically not interested in members created later than the given creation time, but does not understand the SubstringRelation, the client MUST still prune the relation. -If however it is only interested in members created later than the given creation time, it cannot prune all other relations. +Note: If the client comes across a relation subclass it did not code against or did not formulate a condition against, it can ignore this relation when assessing whether pruning is possible. I.e., in the example above, when the client is specifically not interested in members created later than the given creation time, but does not understand the SubstringRelation, the client MUST still prune the relation. While each type of relation can decide on their own properties, relations will often use the `tree:path` to indicate the path from the member to the object on which the `tree:Relation` applies. @@ -223,17 +218,18 @@ Note: A server MAY link the `tree:path` to a property that is not materialized i ## Comparing strings ## {#strings} String values have three specific type of relations: the `tree:PrefixRelation`, the `tree:SubstringRelation` and the `tree:SuffixRelation`. - -Issue: Proposal would be to include that the string comparison should be done using [unicode caseless canonical equivalence](https://icu4c-demos.unicode.org/icu-bin/scompare#a_Equiv_Caseless). However, the fact we would do this in a caseless manner is not consistent with the current spec further on case sensitive unicode ordering and the note on the multiple relations. +The string comparison happens using the unicode canonical equivalence. Issue: We experimented with server-chosen locales such that `ça suffit` can also be found when following a `tree:PrefixRelation` with a `tree:value "c"` (which at this moment is not supported). That would require an understanding of locales, and [browser/JavaScript support for locales is too low to be useful at this point](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_identification_and_negotiation). Also the comparator relations such as `tree:GreaterThanRelation` can be used. -The strings MUST then be compared according to *case sensitive unicode ordering*. +The strings MUST then be compared using case sensitive unicode ordering. When a language is set on the `tree:value`, the relation only refers to these language strings. If no language is indicated, it refers to all (including those without). -Note: If you want to have one resource containing both `e` and `é` as a prefix, you will have to create multiple relations to the same `tree:Node`. +Particular to the `tree:SubstringRelation`, is that multiple `tree:value` properties can be set. This means the members properties will contain all of the given substrings. + +Issue: We need a flag for setting case insensitiveness: what will we use? In previous implementations `sh:flags "i"` was used. ## Comparing named nodes ## {#named-nodes} @@ -249,12 +245,15 @@ When using `tree:GeospatiallyContainsRelation`, the `tree:path` MUST refer to a ## Comparing time literals ## {#time} When using relations such as `tree:LessThanRelation` or `tree:GreaterThanRelation`, the time literals MUST to be compared according to these 3 possible data types: `xsd:date`, `xsd:dateTime` or `xsd:dateTimeStamp`. +It is highly recommended to server developers to provide a timezone in the `tree:value`, which can be done in these datatypes themself. + +When no timezone is specified, the comparison needs to take place on the worst-case bound. For example a date `2022-01-01` without timezone thus represents a period of time of 48 hours from (`[`) `2021-12-31T12:00:00Z` until `2022-01-02T12:00:00Z` (`[`). # Search forms # {#searching} -Searching through a TREE will allow you to immediately jump to the right `tree:Node`. +Searching through a TREE will allow you to immediately jump to the right `tree:Node` in a subtree. TREE relies on the [Hydra search specification](http://www.hydra-cg.com/spec/latest/core/#hydra:search) for its search forms. -It does however extend Hydra with specific search properties (`hydra:IriTemplate`) for different types of search forms, and searches starting from a `tree:ViewDescription`, to which the search form is linked with `tree:search`. +It does however extend Hydra with specific search properties (`hydra:IriTemplate`) for different types of search forms, and searches starting from a specific `tree:Node`, to which the search form is linked with `tree:search`. The behaviour of the search form fully depends on the specific property, for which TREE introduces a couple of specific properties: ## Geospatial XYZ tiles search form ## {#xyztiles} From 534c750f3771ba81660ff7df6df3b5385e7b97ee Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Thu, 26 Sep 2024 09:01:37 +0200 Subject: [PATCH 16/28] Completeness in subtree text --- 01-tree-specification.bs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/01-tree-specification.bs b/01-tree-specification.bs index f40ce94..0cb6d4c 100644 --- a/01-tree-specification.bs +++ b/01-tree-specification.bs @@ -174,13 +174,13 @@ Finally, for geospatial trees, `tree:GeospatiallyContainsRelation` exists. A client decides, based on their own tasks, what type of relations are important to implement. Each relation is a comparator function that helps deciding whether or not the subtree reachable from the `tree:node` link can be pruned. -All relations to the same `tree:node` MUST be combined using a logical AND. - -One relation can be interpreted as a comparator as follows: +A relation can be interpreted as a comparator as follows: 1. The left-hand: what the members in the substree reachable from the linked node will contain w.r.t. the objects reachable from the `tree:path`. 2. The operator: decided by the type of the relation and the datatype or node type of the `tree:value` triple’s object. 3. The right-hand: the `tree:value` triple’s object. +The client MUST combine all relations to the same `tree:node` using a logical AND. +
```turtle <> tree:relation [ @@ -197,11 +197,13 @@ One relation can be interpreted as a comparator as follows: ```
-In the example above the subtree reachable from `ex:Node2` will contain members that are both created later in time than the given timestamp _and_ will have the provided substring in the title. +In the example above the subtree reachable from `ex:Node2` will contain all remaining members that are both created later in time than the given timestamp _and_ will have the provided substring in the title. +The client MAY thus choose to prune all links to other nodes if this is the only thing it is interested in. The client SHOULD prune the subtree reachable from `ex:Node` if it is specifically not looking for members with the given substring, _or_ when it is not interested in members created later in time than the given timestamp. -Alternatively, it MAY score the relation based on the likelihood of returning useful results and created a priority queue that is processed until a top K of results have been found. +Alternatively, it MAY score the relation based on the likelihood of returning useful results and created a priority queue that is processed until a top K of results have been found. -Note: If the client comes across a relation subclass it did not code against or did not formulate a condition against, it can ignore this relation when assessing whether pruning is possible. I.e., in the example above, when the client is specifically not interested in members created later than the given creation time, but does not understand the SubstringRelation, the client MUST still prune the relation. +Note: If the client comes across a relation subclass it did not code against or did not formulate a condition against, it can ignore this relation when assessing whether pruning is possible. +I.e., in the example above, when the client is specifically not interested in members created later than the given creation time, but does not understand the SubstringRelation, the client MUST still prune the relation. While each type of relation can decide on their own properties, relations will often use the `tree:path` to indicate the path from the member to the object on which the `tree:Relation` applies. From 830aff5664bd326905f94b3ea5e43fd2592579a7 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Tue, 1 Oct 2024 17:06:29 +0200 Subject: [PATCH 17/28] Discovery spec in first draft --- 03-discovery-specification.bs | 121 ++++++++++++++++++++-------------- 1 file changed, 73 insertions(+), 48 deletions(-) diff --git a/03-discovery-specification.bs b/03-discovery-specification.bs index 49754e7..5b41bd7 100644 --- a/03-discovery-specification.bs +++ b/03-discovery-specification.bs @@ -11,18 +11,18 @@ Mailing List: public-treecg@w3.org Mailing List Archives: https://lists.w3.org/Archives/Public/public-treecg/ Editor: Pieter Colpaert, https://pietercolpaert.be Abstract: - This specification defines how a client can find specific search trees of interest, as well as list the context information. + This specification defines how a client selects a specific dataset and search tree, as well as extracts relevant context information. -# The overview # {#overview} +# Definitions # {#overview} -A tree:Collection is a subclass of dcat:Dataset ([[!vocab-dcat-3]]). +A `tree:Collection` is a subclass of `dcat:Dataset` ([[!vocab-dcat-3]]). The specialization being that this particular dataset is a collection of _members_. -A tree:SearchTree is a subClassOf dcat:Distribution. +A `tree:SearchTree` is a subClassOf `dcat:Distribution`. The specialization being that it uses the main TREE specification to publish a search tree. -A node from which all other nodes can be found is a `tree:RootNode`, which MAY be explicitely typed as such. +A node from which all other nodes can be found is a `tree:RootNode`. Note: The `tree:SearchTree` and the `tree:RootNode` MAY be identified by the same IRI when no disambiguation is needed. @@ -30,70 +30,95 @@ A TREE client MUST be provided with a URL to start from, which we call the _entr # Initializing a client with a url # {#starting-from} -The goal of the client is to understand what `tree:Collection` it is using, and to find a `tree:RootNode` or search form to start the traversal phase from. +The goal of the client is to understand what `tree:Collection` it is using, and to find a `tree:RootNode` to start the traversal phase from. +This discovery specification extends the initialization step in the TREE specification for the cases in which multiple options are possible. -``` -IN: E: a URL of the entrypoint -OUT: N: tree:RootNode IRI and/or S: search form - ``` +The client MUST dereference the URL, which will result in a set of quads. The client now MUST first perform the init step from the main specification. +If that did not return any result, then the client MUST check whether the URL before redirects (`E`) has been used in one of the following discovery patterns described in the subsections: + 1. `E` is a `tree:Collection`: then the client needs to [select the right search tree](#tree-search-trees) + 2. `E` is a `dcat:Dataset`: then the client needs to [select the right distribution or dataservice from a catalog](#dcat-dataset) + 3. `E` is a `ldes:EventStream`: then the client MAY take into account [LDES specific properties](#ldes) + 4. `E` is a `dcat:Distribution`: then the client needs to [process it accordingly](#dcat-distribution) + 5 `E` is a `dcat:DataService`: then the client needs to [process it accordingly](#dcat-dataservice) + 6. `E` is a catalog or is not explicitly mentioned: then it needs to select a dataset based on [shape information](#tree-collection-shapes) and [DCAT Catalog information](#dcat-catalog) -The client MUST dereference the URL, which will result in a set of quads. -When the URL given to the TREE client, after all redirects, is used in a triple ex:C tree:view <> ., a client MUST assume the URL after redirects (`E'`) is an identifier of the intended `tree:RootNode` of the collection `ex:C`. -The client MUST check for this `tree:view` property and return the result of the discovery algorithm with `<> → N`. +## Selecting a collection via shapes ## {#tree-collection-shapes} -If there is no such triple, then the client MUST check whether the URL before redirects (`E`) has been used in one of the following patterns: - * `E tree:view ?N.` where there’s exactly one `?N`, then the algorithm MUST return `?N → N`. - * `E tree:rootNode ?N ; tree:search ?S .` then the algorithm MUST return `?N → N` and `?S → S`. - * `?DS dcat:servesDataset E ; dcat:endpointURL ?U` or `E dcat:endpointURL ?U`, then the algorithm MUST repeat the algorithm with `?U` as the entrypoint. +When multiple collections are found by a client, it can choose to prune the collections based on the `tree:shape` property. +The `tree:shape` property will refer to a first `sh:NodeShape`. +The collection MAY be pruned in case there is no overlap in properties the client needs. -Note: When data about the dataset, data service or search tree is found, it is a good idea to also pass this on to the client. +Issue: Will we document the precise algorithm to use? Should we extend shapes with cardinality approximations as well? -## tree:Collection ## {#collection} +## Selecting a collection via a catalog ## {#dcat-catalog} -In order to prioritize a specific view link, the relations and search forms in the entry nodes can be studied for their relation types, path or remaining items. -The class tree:ViewDescription indicates a specific TREE structure on a tree:Collection. -Through the property tree:viewDescription a tree:Node can link to an entity that describes the view, and can be reused in data portals as the dcat:DataService. +A DCAT Catalog is an overview of datasets, data services and distributions. +As TREE clients first need to select a dataset, and then a search tree to use, it aligns wll with how DCAT-AP works. +DCAT discovery extends upon the previous section in which a collection or dataset can be selected based on the `tree:shape` property. -
- ```turtle - ## What can be found in a tree:Node - ex:N1 a tree:Node ; - tree:viewDescription ex:View1 . - - ex:C1 a tree:Collection ; - tree:view ex:N1 . - - ## What can be found on a data portal - ex:C1 a dcat:Dataset . - ex:View1 a tree:ViewDescription, dcat:DataService ; - dcat:endpointURL ex:N1 ; # The entry point that can be advertised in a data portal - dcat:servesDataset ex:C1 . - ``` -
+For now, we will assume the DCAT information is available in subject pages. + +Issue: Do we need more text on how to handle different types of DCAT interfaces? + +The dataset descriptions can be used for filtering the datasets available in a catalog to a list of datasets that can be useful for the client. +Such properties may include the spatial extent, the time extent, or how it is possibly a part of another `dcat:Dataset`. + +Issue: How precise do we need to be in this specification? + +When the `dcat:Dataset` is a `tree:Collection`, the DCAT catalog is going to contain a `dct:type` property with `https://w3id.org/tree#Collection` or `https://w3id.org/ldes#EventStream` as the object. + +## Choosing from multiple SearchTrees with TREE ## {#tree-search-trees} + +Issue: This is yet to be done + +## Selecting a search tree via a DCAT dataset ## {#dcat-dataset} + +The are two ways in which you can find a search tree from a dataset: via the distributions and via the data services. Both need to be tested. +Selecting a distribution or data service when multiple are available needs to be done based on [the search tree description](tree-search-trees). +If nothing is available, all need to be tested by processing them as exemplifie din the next subsections. -When there is no tree:viewDescription property in this page, a client either already discovered the description of this view in an earlier tree:Node, either the current tree:Node is implicitly the ViewDescription. Therefore, when the property path tree:view → tree:viewDescription does not yield a result, the view properties MUST be extracted from the object of the tree:view triple. -A tree:Node can also be double typed as the tree:ViewDescription. A client must thus check for ViewDescriptions on both the current node without the tree:viewDescription qualification, as on the current node with the tree:viewDescription link. +### Selecting a search tree via DCAT Distribution ### {#dcat-distribution} -## dcat:Catalog ## {#collection} +`E dcat:distribution ?D . ?D dcat:downloadURL ?N .` then ?N is a rootnode of E. -When multiple collections are found by a client, it can choose to prune the collections based on the tree:shape property. -Therefore a data publisher SHOULD annotate a tree:Collection instance with a SHACL shape. -The tree:shape points to a SHACL description of the shape (sh:NodeShape). +Issue: This is yet to be done -Note: the shape can be a blank node, or a named node on which you should follow your nose when it is defined at a different HTTP URL. +### Selecting a search tree from a DCAT data service ### {#dcat-dataservice} -# Context data # {#context} + * `?DS dcat:servesDataset E ; dcat:endpointURL ?U` or `E dcat:endpointURL ?U`, then the algorithm MUST repeat the algorithm with `?U` as the entrypoint. + +Issue: This is yet to be done + +## Linked Data Event Streams ## {#ldes} + +In case the client is not made for query answering, but only for setting up a replication and synchronization system, then there is a special type that can be used to indicate the search tree is made for this purpose: the `ldes:EventSource`. +Clients that want to prioritize taking a _full_ copy MAY give full priority to this server hint. + +
+```turtle +E a ldes:EventSource ; + tree:rootNode|dcat:downloadURL . +``` +
+ +# Extracting content information # {#context} -Context information is important to understand who the creator of a certain dataset is, when it was last changed, what other datasets it was derived from, etc. +Issue: This is yet to be done -TODO +Context information enabled a cliento understand who the creator of a certain dataset is, when it was last changed, what other datasets it was derived from, etc. ## DCAT and dcterms ## {#context-dcat} +Issue: This is yet to be done + ## Provenance ## {#context-prov} +Issue: This is yet to be done + ## Linked Data Event Streams ## {#context-ldes} +Issue: This is yet to be done + LDES (https://w3id.org/ldes/specification) is a way to evolve search trees in a consistent way. It defines every member as immutable, and a collection as append-only. Therefore, one can make sure to only process each member once. Extra terms are added, such as the concept of an EventStream, retention policies and a timestampPath. From 72efd88903e2a5ea79fd7aaf0dc6a08c9c0e41c4 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Tue, 1 Oct 2024 17:08:59 +0200 Subject: [PATCH 18/28] Fixed typo --- 03-discovery-specification.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/03-discovery-specification.bs b/03-discovery-specification.bs index 5b41bd7..95e977b 100644 --- a/03-discovery-specification.bs +++ b/03-discovery-specification.bs @@ -39,7 +39,7 @@ If that did not return any result, then the client MUST check whether the URL be 2. `E` is a `dcat:Dataset`: then the client needs to [select the right distribution or dataservice from a catalog](#dcat-dataset) 3. `E` is a `ldes:EventStream`: then the client MAY take into account [LDES specific properties](#ldes) 4. `E` is a `dcat:Distribution`: then the client needs to [process it accordingly](#dcat-distribution) - 5 `E` is a `dcat:DataService`: then the client needs to [process it accordingly](#dcat-dataservice) + 5. `E` is a `dcat:DataService`: then the client needs to [process it accordingly](#dcat-dataservice) 6. `E` is a catalog or is not explicitly mentioned: then it needs to select a dataset based on [shape information](#tree-collection-shapes) and [DCAT Catalog information](#dcat-catalog) ## Selecting a collection via shapes ## {#tree-collection-shapes} From e63f5520497e32a9ce0e9e75beac7a3c9436db5c Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Wed, 2 Oct 2024 16:22:14 +0200 Subject: [PATCH 19/28] Writing a better abstract --- 01-tree-specification.bs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/01-tree-specification.bs b/01-tree-specification.bs index 0cb6d4c..18cdb2a 100644 --- a/01-tree-specification.bs +++ b/01-tree-specification.bs @@ -11,8 +11,9 @@ Mailing List: public-treecg@w3.org Mailing List Archives: https://lists.w3.org/Archives/Public/public-treecg/ Editor: Pieter Colpaert, https://pietercolpaert.be Abstract: - TREE hypermedia describes the pagination of a collection of entity descriptions. - It allows clients to follow their nose through a search tree based information structure. + The TREE specifications allows clients to traverse Web APIs that are structured according to a search tree. + It introduces a collection of members distributed across pages called Nodes. + The nodes are interlinked using qualified relations and search forms. # Overview # {#overview} From ff6586e2c833fcc23376b921f7f2ef9c8c6e821b Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Wed, 2 Oct 2024 16:41:41 +0200 Subject: [PATCH 20/28] Fixed typos and left-hand right-hand explanation --- 01-tree-specification.bs | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/01-tree-specification.bs b/01-tree-specification.bs index 18cdb2a..40afd90 100644 --- a/01-tree-specification.bs +++ b/01-tree-specification.bs @@ -164,31 +164,33 @@ When dereferencing the object of a `tree:node` triple, the client MUST follow re Note: Allowing redirects allows servers to rebalance their search trees over time. -A client MAY assume completeness of members intended by the search tree when it derefenced all node links. +A client can assume completeness of members intended by the search tree when it derefenced all node links. # Pruning branches # {#relationsubclasses} -In search trees, a `tree:Relation` will likely be typed using one of its subclasses. -For partial string matching, `tree:PrefixRelation`, `tree:SubstringRelation`, and `tree:SuffixRelation` exist. -For comparing various datatypes, `tree:GreaterThanRelation`, `tree:GreaterThanOrEqualToRelation`, `tree:LessThanRelation`, `tree:LessThanOrEqualToRelation`, `tree:EqualToRelation`, and `tree:NotEqualToRelation` exist. -Finally, for geospatial trees, `tree:GeospatiallyContainsRelation` exists. +In search trees, a `tree:Relation` will likely be typed using one of its subclasses: + * For partial string matching, `tree:PrefixRelation`, `tree:SubstringRelation`, and `tree:SuffixRelation` exist. + * For comparing various datatypes, `tree:GreaterThanRelation`, `tree:GreaterThanOrEqualToRelation`, `tree:LessThanRelation`, `tree:LessThanOrEqualToRelation`, `tree:EqualToRelation`, and `tree:NotEqualToRelation` exist. + * Finally, for geospatial trees, `tree:GeospatiallyContainsRelation` exists. A client decides, based on their own tasks, what type of relations are important to implement. Each relation is a comparator function that helps deciding whether or not the subtree reachable from the `tree:node` link can be pruned. A relation can be interpreted as a comparator as follows: - 1. The left-hand: what the members in the substree reachable from the linked node will contain w.r.t. the objects reachable from the `tree:path`. + 1. The left-hand: what the members in the subtree reachable from the linked node will contain w.r.t. the objects reachable from the `tree:path`. 2. The operator: decided by the type of the relation and the datatype or node type of the `tree:value` triple’s object. 3. The right-hand: the `tree:value` triple’s object. The client MUST combine all relations to the same `tree:node` using a logical AND. +The members that the client is able to find in a subtree will be complete relative to the position in the search tree. +
```turtle <> tree:relation [ - a tree:GreaterThanRelation ; - tree:node ex:Node2 ; - tree:path dct:created ; - tree:value "2024-12-16T12:00:00Z"^^xsd:dateTime + a tree:GreaterThanRelation ; # the type of the relation deciding the operator + tree:node ex:Node2 ; # for the left-hand: all members from here + tree:path dct:created ; # for the left-hand: the path pointing at the term(s) in the member + tree:value "2024-12-16T12:00:00Z"^^xsd:dateTime # the right-hand ],[ a tree:SubstringRelation ; tree:node ex:Node2 ; @@ -198,13 +200,13 @@ The client MUST combine all relations to the same `tree:node` using a logical AN ```
-In the example above the subtree reachable from `ex:Node2` will contain all remaining members that are both created later in time than the given timestamp _and_ will have the provided substring in the title. -The client MAY thus choose to prune all links to other nodes if this is the only thing it is interested in. -The client SHOULD prune the subtree reachable from `ex:Node` if it is specifically not looking for members with the given substring, _or_ when it is not interested in members created later in time than the given timestamp. -Alternatively, it MAY score the relation based on the likelihood of returning useful results and created a priority queue that is processed until a top K of results have been found. - -Note: If the client comes across a relation subclass it did not code against or did not formulate a condition against, it can ignore this relation when assessing whether pruning is possible. -I.e., in the example above, when the client is specifically not interested in members created later than the given creation time, but does not understand the SubstringRelation, the client MUST still prune the relation. +
+In the example above the subtree reachable from `ex:Node2` will contain all remaining members that are both created later in time than the given timestamp *and* will have the provided substring in the title. +The client can choose to prune all links to other nodes if this is the only thing it is interested in. +Alternatively, the client can choose prune the subtree reachable from `ex:Node2` if it is specifically not looking for members with the given substring, *or* when it is not interested in members created later in time than the given timestamp. +Alternatively, it can also score the relation based on the likelihood of returning useful results and created a priority queue that is processed until a top K of results have been found. +Mind that when the client is specifically not interested in members created later than the given creation time, but does not understand the SubstringRelation, the client can still prune the relation. +
While each type of relation can decide on their own properties, relations will often use the `tree:path` to indicate the path from the member to the object on which the `tree:Relation` applies. @@ -216,7 +218,7 @@ When multiple results from the path are found, they need to be interpreted as a A client, in case it wants to process relations that use the `tree:path` property, MUST implement a matching algorithm to check whether the relation is relevant. I.e., a `tree:path` on `(rdfs:label [sh:alternativePath rdfs:comment ] )` will be useful when the client is tasked to filter on `rdfs:comment`. -Note: A server MAY link the `tree:path` to a property that is not materialized in the current response. For the client, if it also needs those triples, we assume in this spec that the client has another way of retrieving those, or already retrieved them from another source. +Note: A server is allowed to refer the `tree:path` to a property that is not materialized in the current response. For the client, if it also needs those triples, we assume in this spec that the client has another way of retrieving those, or already retrieved them from another source. ## Comparing strings ## {#strings} From 627126768386d580c1b17e0731a2f01daf25cf89 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Wed, 2 Oct 2024 16:45:09 +0200 Subject: [PATCH 21/28] Link concept of Nodes, Search Tree and Collection in definitions --- 01-tree-specification.bs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/01-tree-specification.bs b/01-tree-specification.bs index 40afd90..329b323 100644 --- a/01-tree-specification.bs +++ b/01-tree-specification.bs @@ -112,9 +112,9 @@ A `tree:Node` is part of a search tree, and apart from the root node, it has exa A `tree:search` form is an IRI template, that when filled out with the right parameters becomes a `tree:Node` IRI, or when dereferenced will redirect to a `tree:Node` from which all members in the collection that adhere to the described comparator can be found. -A search tree is a set of interlinked `tree:Node`s. +A search tree is the -- in this document -- implicit concept of a set of interlinked `tree:Node`s publishing a `tree:Collection`. It will adhere to a certain growth or tree balancing strategy. -In one tree, completeness MUST be guaranteed, unless indicated otherwise using a retention policy (as is possible in LDES). +In one tree, completeness MUST be guaranteed, unless indicated otherwise (as is possible in LDES using a retention policy). # Initialization # {#init} From 0414da4e84e9af8ac2d2d8b39b0056554a6f4629 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Mon, 7 Oct 2024 15:40:41 +0200 Subject: [PATCH 22/28] Image should be in spec to make it version controlled (bergos) --- 01-tree-specification.bs | 2 +- TREE-overview.svg | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 TREE-overview.svg diff --git a/01-tree-specification.bs b/01-tree-specification.bs index 329b323..88a2493 100644 --- a/01-tree-specification.bs +++ b/01-tree-specification.bs @@ -18,7 +18,7 @@ Abstract: # Overview # {#overview} -An overview of the TREE specification with the TREE collection, a reference to the first focus node of its members, and the relations to other nodes from the current node. +An overview of the TREE specification with the TREE collection, a reference to the first focus node of its members, and the relations to other nodes from the current node.
The TREE specification introduces these core concepts: * a `tree:Collection` is a set of members. It typically has these properties when described in a node: diff --git a/TREE-overview.svg b/TREE-overview.svg new file mode 100644 index 0000000..91d6adf --- /dev/null +++ b/TREE-overview.svg @@ -0,0 +1 @@ + \ No newline at end of file From 7ee0d187ead61f78c8de2cedd08992642f911d1b Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Mon, 7 Oct 2024 15:42:51 +0200 Subject: [PATCH 23/28] Consistent `a` prefix in overview --- 01-tree-specification.bs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/01-tree-specification.bs b/01-tree-specification.bs index 88a2493..2c9408a 100644 --- a/01-tree-specification.bs +++ b/01-tree-specification.bs @@ -21,19 +21,19 @@ Abstract: An overview of the TREE specification with the TREE collection, a reference to the first focus node of its members, and the relations to other nodes from the current node.
The TREE specification introduces these core concepts: - * a `tree:Collection` is a set of members. It typically has these properties when described in a node: + * `tree:Collection` is a set of members. It typically has these properties when described in a node: - `tree:member` points at the first focus node from which to retrieve and extract all quads of a member - `tree:view` points to the `tree:Node` you are currently visiting - `tree:shape` indicates the [[!SHACL]] shape (exactly one) to which each member in the collection adheres - * a `tree:Node`: is a page in the search tree + * `tree:Node` is a page in the search tree - `tree:relation` points at relations to other node - - a `tree:search` describes a search form that allows an agent to jump to a specific `tree:Node` in the (sub)tree from this node + - `tree:search` describes a search form that allows an agent to jump to a specific `tree:Node` in the (sub)tree from this node - `tree:viewDescription` points to an entity with a reusable piece of information relevant to the full search tree. Multiple descriptions MUST be combined. - * a `tree:Relation` is a relation from one node to another. An extension of this class indicates a specific type of relation (e.g., a `tree:GreaterThanRelation`). A relation typically has these properties: - - a `tree:node` the URL of the other node - - a `tree:path` indicating to which of the members' properties this relation applies - - a `tree:value` indicating a value constraint on the members' values - - a `tree:remainingItems` defining how many members can be reached when following this relation + * `tree:Relation` is a relation from one node to another. An extension of this class indicates a specific type of relation (e.g., a `tree:GreaterThanRelation`). A relation typically has these properties: + - `tree:node` is the URL of the other node + - `tree:path` indicates to which of the members' properties this relation applies + - `tree:value` indicates a value constraint on the members' values + - `tree:remainingItems` defines how many members can be reached when following this relation A simple collection can be created as illustrated in the following example:
From c8f0b58bf0eb4864c2bf33674ffda3bbc4d1bfb5 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Mon, 7 Oct 2024 15:45:20 +0200 Subject: [PATCH 24/28] Typo in discovery --- 03-discovery-specification.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/03-discovery-specification.bs b/03-discovery-specification.bs index 95e977b..3b12299 100644 --- a/03-discovery-specification.bs +++ b/03-discovery-specification.bs @@ -105,7 +105,7 @@ E a ldes:EventSource ; Issue: This is yet to be done -Context information enabled a cliento understand who the creator of a certain dataset is, when it was last changed, what other datasets it was derived from, etc. +Context information enables a client to understand who the creator of a certain dataset is, when it was last changed, what other datasets it was derived from, etc. ## DCAT and dcterms ## {#context-dcat} From 076b3b1423db710d96da617671256e2634cc2233 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Mon, 7 Oct 2024 15:47:27 +0200 Subject: [PATCH 25/28] Fixed feedback by xdxxxdx --- 01-tree-specification.bs | 8 ++++---- 03-discovery-specification.bs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/01-tree-specification.bs b/01-tree-specification.bs index 2c9408a..616d86f 100644 --- a/01-tree-specification.bs +++ b/01-tree-specification.bs @@ -137,7 +137,7 @@ Note: Having an identifier for the collection has become mandatory: without it y # The member extraction algorithm # {#member-extraction-algorithm} The member extraction algorithm allows a data publisher to define their members in different ways: - 1. As in the examples above: all quads with the object of the `tree:member` quads as a subject (and recursively the quads of their blank nodes) are by default included (see also [[!CBD]]), except when they would explicitely not be included in case 3, when the shape would be closed. + 1. As in the examples above: all quads with the object of the `tree:member` quads as a subject (and recursively the quads of their blank nodes) are by default included (see also [[!CBD]]), except when they would explicitly not be included in case 3, when the shape would be closed. 2. Out of band / in band: - when no quads of a member have been found, the member will be dereferenced. This allows to publish the member on a separate page. - part of the member can be maintained elsewhere when a shape is defined (see 3) @@ -145,8 +145,8 @@ The member extraction algorithm allows a data publisher to define their members 4. By putting the triples in a named graph of the object of `tree:member`, all these triples will be matched. Depending on the goals of the client, it MAY implement the member extraction algorithm to fetch all triples about the entity as intended by the server. -The method used withun TREE is combination of Concise Bounded Descriptions [[!CBD]], named graphs and the topology of a shape (deducted from the `tree:shape`). -The full algorithm is specificied in the [shape topologies](https://w3id.org/tree/specification/shape-topologies) report. +The method used within TREE is combination of Concise Bounded Descriptions [[!CBD]], named graphs and the topology of a shape (deducted from the `tree:shape`). +The full algorithm is specified in the [shape topologies](https://w3id.org/tree/specification/shape-topologies) report. # Traversing the search tree # {#traversing} @@ -265,7 +265,7 @@ The behaviour of the search form fully depends on the specific property, for whi Three properties allow to specify a geospatial XYZ tiles template (also known as slippy maps). 1. `tree:longitudeTile` describes the X value - 2. `tree:latitudeTile` descrbes the Y value + 2. `tree:latitudeTile` describes the Y value 3. `tree:zoom` describes the zoom level All properties expect positive integers. diff --git a/03-discovery-specification.bs b/03-discovery-specification.bs index 3b12299..935fd8b 100644 --- a/03-discovery-specification.bs +++ b/03-discovery-specification.bs @@ -53,7 +53,7 @@ Issue: Will we document the precise algorithm to use? Should we extend shapes wi ## Selecting a collection via a catalog ## {#dcat-catalog} A DCAT Catalog is an overview of datasets, data services and distributions. -As TREE clients first need to select a dataset, and then a search tree to use, it aligns wll with how DCAT-AP works. +As TREE clients first need to select a dataset, and then a search tree to use, it aligns with how DCAT-AP works. DCAT discovery extends upon the previous section in which a collection or dataset can be selected based on the `tree:shape` property. For now, we will assume the DCAT information is available in subject pages. From 5a5cc0f359ca52a3916dbe0cf6c11e4412bf6527 Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Mon, 7 Oct 2024 16:41:15 +0200 Subject: [PATCH 26/28] Processed comment @julianrojas87 --- 03-discovery-specification.bs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/03-discovery-specification.bs b/03-discovery-specification.bs index 935fd8b..751eddb 100644 --- a/03-discovery-specification.bs +++ b/03-discovery-specification.bs @@ -31,7 +31,7 @@ A TREE client MUST be provided with a URL to start from, which we call the _entr # Initializing a client with a url # {#starting-from} The goal of the client is to understand what `tree:Collection` it is using, and to find a `tree:RootNode` to start the traversal phase from. -This discovery specification extends the initialization step in the TREE specification for the cases in which multiple options are possible. +This discovery specification extends the initialization step in the TREE specification, for the cases in which multiple options are possible. The client MUST dereference the URL, which will result in a set of quads. The client now MUST first perform the init step from the main specification. If that did not return any result, then the client MUST check whether the URL before redirects (`E`) has been used in one of the following discovery patterns described in the subsections: @@ -39,14 +39,14 @@ If that did not return any result, then the client MUST check whether the URL be 2. `E` is a `dcat:Dataset`: then the client needs to [select the right distribution or dataservice from a catalog](#dcat-dataset) 3. `E` is a `ldes:EventStream`: then the client MAY take into account [LDES specific properties](#ldes) 4. `E` is a `dcat:Distribution`: then the client needs to [process it accordingly](#dcat-distribution) - 5. `E` is a `dcat:DataService`: then the client needs to [process it accordingly](#dcat-dataservice) + 5. `E` is a `dcat:DataService`: then the client needs to [process it accordingly](#dcat-dataservice) 6. `E` is a catalog or is not explicitly mentioned: then it needs to select a dataset based on [shape information](#tree-collection-shapes) and [DCAT Catalog information](#dcat-catalog) ## Selecting a collection via shapes ## {#tree-collection-shapes} When multiple collections are found by a client, it can choose to prune the collections based on the `tree:shape` property. The `tree:shape` property will refer to a first `sh:NodeShape`. -The collection MAY be pruned in case there is no overlap in properties the client needs. +The collection MAY be pruned in case there is no overlap with the properties the client needs. Issue: Will we document the precise algorithm to use? Should we extend shapes with cardinality approximations as well? From acd1c31a9de2adf56d00e557b1f330111f57ca8c Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Tue, 8 Oct 2024 09:31:50 +0200 Subject: [PATCH 27/28] Abstract --- 01-tree-specification.bs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/01-tree-specification.bs b/01-tree-specification.bs index 616d86f..63f071e 100644 --- a/01-tree-specification.bs +++ b/01-tree-specification.bs @@ -11,9 +11,10 @@ Mailing List: public-treecg@w3.org Mailing List Archives: https://lists.w3.org/Archives/Public/public-treecg/ Editor: Pieter Colpaert, https://pietercolpaert.be Abstract: - The TREE specifications allows clients to traverse Web APIs that are structured according to a search tree. - It introduces a collection of members distributed across pages called Nodes. - The nodes are interlinked using qualified relations and search forms. + The TREE specification provides instructions for clients to interpret and navigate Web APIs structured as search trees. + It defines how members (sets of quads) in a dataset can be distributed across multiple pages interlinked through relationships. + The specification introduces key concepts such as `tree:Collection` (a set of members), `tree:Node` (the pages in the search tree), and `tree:Relation` (links between nodes). + By interpreting such qualified relations and search forms, TREE enables clients to efficiently retrieve their members of interest. # Overview # {#overview} @@ -26,8 +27,8 @@ The TREE specification introduces these core concepts: - `tree:view` points to the `tree:Node` you are currently visiting - `tree:shape` indicates the [[!SHACL]] shape (exactly one) to which each member in the collection adheres * `tree:Node` is a page in the search tree - - `tree:relation` points at relations to other node - - `tree:search` describes a search form that allows an agent to jump to a specific `tree:Node` in the (sub)tree from this node + - `tree:relation` points at relations to other nodes + - `tree:search` describes a search form that allows an agent to jump from this node to a specific `tree:Node` in the (sub)tree - `tree:viewDescription` points to an entity with a reusable piece of information relevant to the full search tree. Multiple descriptions MUST be combined. * `tree:Relation` is a relation from one node to another. An extension of this class indicates a specific type of relation (e.g., a `tree:GreaterThanRelation`). A relation typically has these properties: - `tree:node` is the URL of the other node From 011d2a764e6a689341270b19892f2afda5dd4f2e Mon Sep 17 00:00:00 2001 From: Pieter Colpaert Date: Tue, 8 Oct 2024 09:35:21 +0200 Subject: [PATCH 28/28] Remove examples for now --- examples/eventstreams/README.md | 82 ------------------ .../first.ttl | 58 ------------- .../second.ttl | 42 ---------- .../stops.ttl | 12 --- .../paged-collection-with-order/first.ttl | 48 ----------- .../paged-collection-with-order/second.ttl | 44 ---------- .../5467/2020-12-25T14%3A00%3A00.000Z.ttl | 67 --------------- .../5467/2020-12-25T15%3A00%3A00.000Z.ttl | 70 ---------------- .../timeseries/airQualityObservations.ttl | 84 ------------------- 9 files changed, 507 deletions(-) delete mode 100644 examples/eventstreams/README.md delete mode 100644 examples/geospatially-ordered-public-transport/first.ttl delete mode 100644 examples/geospatially-ordered-public-transport/second.ttl delete mode 100644 examples/geospatially-ordered-public-transport/stops.ttl delete mode 100644 examples/paged-collection-with-order/first.ttl delete mode 100644 examples/paged-collection-with-order/second.ttl delete mode 100644 examples/timeseries/14/8393/5467/2020-12-25T14%3A00%3A00.000Z.ttl delete mode 100644 examples/timeseries/14/8393/5467/2020-12-25T15%3A00%3A00.000Z.ttl delete mode 100644 examples/timeseries/airQualityObservations.ttl diff --git a/examples/eventstreams/README.md b/examples/eventstreams/README.md deleted file mode 100644 index 4caf2f5..0000000 --- a/examples/eventstreams/README.md +++ /dev/null @@ -1,82 +0,0 @@ -# Example: Event Streams - -Event streams in TREE are defined as a `tree:Collection` of members with event-like objects. Each of such member has a timestamp (preferably with range `xsd:dateTime`) such as a `prov:generatedAtTime` indicating the time at which the event was created. -On each collection, a `tree:shape` __should__ be set that links to a SHACL shape to which the events comply. - -Example: - -```turtle - a tree:Collection ; - tree:shape ; # this shacl shape for as long as this collection exists will need to be backwards compatible. - tree:member . - - a sosa:Observation ; - sosa:resultTime "2020..." ; - sosa:hasSimpleResult "1" . -``` - -When implementing an event stream on top of a data model that does not have the concept of things that live in time, you will have to extend that model. One can solve that by using the concept of versions (using the predicate `dcterms:isVersionOf` in dcterms as in the following example: - -```turtle - a tree:Collection ; - tree:shape ; - tree:member . - - prov:generatedAtTime "2021-01-01T00:00:00Z" ; - adms:versionNotes "First version of this address. It was added in 2021." ; - dcterms:isVersionOf ; - dcterms:title "Streetname X, ZIP Municipality, Country" . -``` - -A SPARQL query then has to query for version of this object as a way to give time-context to the query: - -```sparql -SELECT * WHERE { - ?address dcterms:isVersionOf ; - prov:generatedAtTime ?created ; - dcterms:title ?addressString . -} ORDER BY DESC ?created LIMIT 1 -``` - -A CONSTRUCT query can thus materialize the last version as follows: - -```sparql -CONSTRUCT { - dcterms:title ?addressString . -} WHERE { - ?address dcterms:isVersionOf ; - prov:generatedAtTime ?created ; - dcterms:title ?addressString . -} ORDER BY DESC ?created LIMIT 1 -``` - -## Fragmentation strategies - -The main interesting fragmentation strategy for an event stream is to split it in time. -This can be done with simple TREE relations such as: `tree:GreaterThanOrEqualToRelation` and `tree:LessThanOrEqualToRelation`. - -The first page of the event stream starts with the oldest events: - -```turtle - a tree:Collection ; - tree:shape ; # this shacl shape for as long as this collection exists will need to be backwards compatible. - tree:member , ... ; - tree:view . - - a tree:Node ; - tree:relation [ - a tree:GreaterThanOrEqualToRelation ; - tree:path sosa:resultTime ; - tree:node ; - tree:value "2020-12-24T12:00:00Z"^^xsd:dateTime - ] . -``` - -Also other links can be added to later pages. - -A `tree:importStream` can be used on the last page to import events through pubsub as they happen in time. - -## Hydra search forms - -Using a `hydra:search` form with `hydra:property` `tree:timeQuery` you may add a search form to directly address a certain page containing events in a time interval. - diff --git a/examples/geospatially-ordered-public-transport/first.ttl b/examples/geospatially-ordered-public-transport/first.ttl deleted file mode 100644 index f9f5374..0000000 --- a/examples/geospatially-ordered-public-transport/first.ttl +++ /dev/null @@ -1,58 +0,0 @@ -@prefix tree: . -@prefix hydra: . -@prefix dcterms: . -@prefix rdfs: . -@prefix schema: . -@prefix shacl: . -@prefix lc: . -@prefix gtfs: . -@prefix geosparql: . -@prefix xsd: . - - a hydra:Collection ; - rdfs:label "All arrivals and departures of Trains in Belgium"@en ; - tree:view . #From the first page, all elements can be found - - a tree:Node ; - tree:relation [ - a tree:GreaterThanOrEqualToRelation ; - tree:node ; - tree:path lc:departureTime ; - tree:value "2020-03-16T08:30:00.000Z"^^xsd:dateTime - ], - [ - a tree:GeospatiallyContainsRelation ; - tree:node ; - tree:path (lc:departureStop geosparql:asWKT) ; - tree:import ; - tree:value "POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))"^^geosparql:wktLiteral - ]. - - hydra:member , - . - -## The data itself - a lc:Connection; - lc:arrivalDelay "240"^^xsd:integer ; - lc:arrivalStop ; - lc:arrivalTime "2020-03-16T08:45:00.000Z"^^xsd:dateTime ; - lc:departureDelay "360"^^xsd:integer ; - lc:departureStop ; - lc:departureTime "2020-03-16T08:28:00.000Z"^^xsd:dateTime ; - gtfs:dropOffType gtfs:Regular; - gtfs:headsign "Ostende"; - gtfs:pickupType gtfs:Regular; - gtfs:route ; - gtfs:trip . - a lc:Connection; - lc:arrivalDelay "180"^^xsd:integer ; - lc:arrivalStop ; - lc:arrivalTime "2020-03-16T08:56:00.000Z"^^xsd:dateTime ; - lc:departureDelay "180"^^xsd:integer ; - lc:departureStop ; - lc:departureTime "2020-03-16T08:29:00.000Z"^^xsd:dateTime ; - gtfs:dropOffType gtfs:Regular ; - gtfs:headsign "Bruges" ; - gtfs:pickupType gtfs:Regular ; - gtfs:route ; - gtfs:trip . \ No newline at end of file diff --git a/examples/geospatially-ordered-public-transport/second.ttl b/examples/geospatially-ordered-public-transport/second.ttl deleted file mode 100644 index d16effa..0000000 --- a/examples/geospatially-ordered-public-transport/second.ttl +++ /dev/null @@ -1,42 +0,0 @@ -@prefix tree: . -@prefix hydra: . -@prefix dcterms: . -@prefix rdfs: . -@prefix schema: . -@prefix shacl: . -@prefix lc: . -@prefix gtfs: . -@prefix xsd: . - - a hydra:Collection ; - rdfs:label "All arrivals and departures of Trains in Belgium"@en ; - tree:view ; - hydra:member , - . - -## The data itself - - a lc:Connection; - lc:arrivalDelay "60"^^xsd:integer; - lc:arrivalStop ; - lc:arrivalTime "2020-03-16T09:12:00.000Z"^^xsd:dateTime; - lc:departureDelay "180"^^xsd:integer; - lc:departureStop ; - lc:departureTime "2020-03-16T08:32:00.000Z"^^xsd:dateTime; - gtfs:dropOffType gtfs:Regular; - gtfs:headsign "Bruges"; - gtfs:pickupType gtfs:Regular; - gtfs:route ; - gtfs:trip . - a lc:Connection; - lc:arrivalDelay "0"^^xsd:integer>; - lc:arrivalStop ; - lc:arrivalTime "2020-03-16T09:02:00.000Z"^^xsd:dateTime; - lc:departureDelay "0"^^xsd:integer; - lc:departureStop ; - lc:departureTime "2020-03-16T08:36:00.000Z"^^xsd:dateTime; - gtfs:dropOffType gtfs:Regular; - gtfs:headsign "Zottegem"; - gtfs:pickupType gtfs:Regular; - gtfs:route ; - gtfs:trip . \ No newline at end of file diff --git a/examples/geospatially-ordered-public-transport/stops.ttl b/examples/geospatially-ordered-public-transport/stops.ttl deleted file mode 100644 index ea87971..0000000 --- a/examples/geospatially-ordered-public-transport/stops.ttl +++ /dev/null @@ -1,12 +0,0 @@ -@prefix rdfs: . -@prefix gtfs: . -@prefix geo: . -@prefix geosparql: . -@prefix xsd: . - - - a gtfs:Stop ; - rdfs:label "Izegem"@nl ; - geo:latitude 50.9211500 ; - geo:longitude 3.21208900 ; - geosparql:asWKT "POINT (3.21208900 50.9211500)"^^geosparql:wktLiteral . diff --git a/examples/paged-collection-with-order/first.ttl b/examples/paged-collection-with-order/first.ttl deleted file mode 100644 index 68e9589..0000000 --- a/examples/paged-collection-with-order/first.ttl +++ /dev/null @@ -1,48 +0,0 @@ -@prefix tree: . -@prefix hydra: . -@prefix dcterms: . -@prefix rdfs: . -@prefix schema: . -@prefix shacl: . -@prefix lc: . -@prefix xsd: . - - a hydra:Collection ; - rdfs:label "All arrivals and departures of Trains in Belgium"@en ; - tree:view . #From the first page, all elements can be found - - a tree:Node ; - tree:relation [ - a tree:GreaterThanRelation ; - tree:node ; - tree:path lc:departureTime ; - tree:value "2019-07-23T06:30:00.000Z"^^xsd:dateTime - ]. - - hydra:member , . - -## The data itself - a lc:Connection; - lc:arrivalDelay "240"^^; - lc:arrivalStop ; - lc:arrivalTime "2019-07-23T06:19:00.000Z"^^; - lc:departureDelay "360"^^; - lc:departureStop ; - lc:departureTime "2019-07-23T06:14:00.000Z"^^; - ; - "Ostende"; - ; - ; - . - a lc:Connection; - lc:arrivalDelay "180"^^; - lc:arrivalStop ; - lc:arrivalTime "2019-07-23T06:31:00.000Z"^^; - lc:departureDelay "180"^^; - lc:departureStop ; - lc:departureTime "2019-07-23T06:28:00.000Z"^^; - ; - "Bruges"; - ; - ; - . diff --git a/examples/paged-collection-with-order/second.ttl b/examples/paged-collection-with-order/second.ttl deleted file mode 100644 index 2f243de..0000000 --- a/examples/paged-collection-with-order/second.ttl +++ /dev/null @@ -1,44 +0,0 @@ -@prefix tree: . -@prefix hydra: . -@prefix dcterms: . -@prefix rdfs: . -@prefix schema: . -@prefix shacl: . -@prefix lc: . -@prefix xsd: . -@prefix void: . - - a hydra:Collection ; - rdfs:label "All arrivals and departures of Trains in Belgium"@en ; - void:subset ; #using the more general void:subset, as not the entire collection can be found from this node as there is no backlink - hydra:member , . - -## The data itself - - a lc:Connection; - lc:arrivalDelay "60"^^; - lc:arrivalStop ; - lc:arrivalTime "2019-07-23T06:36:00.000Z"^^; - lc:departureDelay "180"^^; - lc:departureStop ; - lc:departureTime "2019-07-23T06:32:00.000Z"^^; - ; - "Bruges"; - ; - ; - . - a lc:Connection; - lc:arrivalDelay "0"^^; - lc:arrivalStop ; - lc:arrivalTime "2019-07-23T06:44:00.000Z"^^; - lc:departureDelay "0"^^; - lc:departureStop ; - lc:departureTime "2019-07-23T06:36:00.000Z"^^; - ; - "Zottegem"; - ; - ; - . - - - diff --git a/examples/timeseries/14/8393/5467/2020-12-25T14%3A00%3A00.000Z.ttl b/examples/timeseries/14/8393/5467/2020-12-25T14%3A00%3A00.000Z.ttl deleted file mode 100644 index 5f6c274..0000000 --- a/examples/timeseries/14/8393/5467/2020-12-25T14%3A00%3A00.000Z.ttl +++ /dev/null @@ -1,67 +0,0 @@ -@prefix tree: . -@prefix hydra: . -@prefix dcterms: . -@prefix rdfs: . -@prefix lc: . -@prefix xsd: . -@prefix sosa: . -@prefix tiles: . -@prefix geo: . -@prefix cot: . -@prefix sh: . -@prefix geosparql: . -@prefix void: . - - a tree:Node ; - dcterms:isPartOf ; - # Historic data ends here - # Only a relation to go forward in time - tree:relation [ a tree:GreaterThanOrEqualToRelation ; - tree:node ; - tree:path sosa:resultTime ; - tree:value "2020-12-25T15:00:00.000Z"^^xsd:dateTime - ]; - tiles:longitudeTile "8393" ; - tiles:latitudeTile "5467"; - tiles:zoom "14"; - tree:timeQuery "2020-12-25T14:00:00.000Z"^^xsd:dateTime ; # the user followed the LowerThanRelation link from node to this node - tree:search _:b0 . - - - a tree:Collection ; - tree:view ; - void:subset ; - tree:member _:b1, _:b2, _:b3 . - -# Specific search form within this tile -_:b0 a hydra:IriTemplate ; - hydra:variableRepresentation hydra:BasicRepresentation ; - hydra:template "https://lodi.ilabt.imec.be/air/14/8393/5467/{t}"; - hydra:mapping [ a hydra:IriTemplateMapping ; - hydra:variable "t" ; - tree:path sosa:resultTime ; - hydra:property tree:timeQuery ; - hydra:required "false"^^xsd:boolean - ] . - -## The data itself -_:b1 a sosa:Observation; - sosa:resultTime "2020-12-25T14:05:00.000Z"^^xsd:dateTime ; - sosa:hasFeatureOfInterest <#Airquality/lat=51.23759466223419&long=4.415932092815638>, cot:AirQuality ; - sosa:observedProperty cot:PM1 . - -_:b2 a sosa:Observation ; - sosa:resultTime "2020-12-25T14:15:00.000Z"^^xsd:dateTime ; - sosa:hasFeatureOfInterest <#Airquality/lat=51.23759466223419&long=4.415932092815638>, cot:AirQuality ; - sosa:observedProperty cot:PM10 . - -_:b3 a sosa:Observation ; - sosa:resultTime "2020-12-25T14:55:00.000Z"^^xsd:dateTime ; - sosa:hasFeatureOfInterest <#Airquality/lat=51.23759466223419&long=4.415932092815638>, cot:AirQuality ; - sosa:observedProperty cot:NO2 . - -<#Airquality/lat=51.23759466223419&long=4.415932092815638> a sosa:FeatureOfInterest; - rdfs:label "Air quality at this point location"; - geosparql:asWKT "POINT (4.426460266113281 51.24171563651943)"^^geosparql:wktLiteral ; - geo:latitude "51.23759466223419"; - geo:longitude "4.415932092815638". \ No newline at end of file diff --git a/examples/timeseries/14/8393/5467/2020-12-25T15%3A00%3A00.000Z.ttl b/examples/timeseries/14/8393/5467/2020-12-25T15%3A00%3A00.000Z.ttl deleted file mode 100644 index c9f24dd..0000000 --- a/examples/timeseries/14/8393/5467/2020-12-25T15%3A00%3A00.000Z.ttl +++ /dev/null @@ -1,70 +0,0 @@ -@prefix tree: . -@prefix hydra: . -@prefix dcterms: . -@prefix rdfs: . -@prefix lc: . -@prefix xsd: . -@prefix sosa: . -@prefix tiles: . -@prefix geo: . -@prefix cot: . -@prefix sh: . -@prefix geosparql: . -@prefix void: . - - a tree:Node ; - dcterms:isPartOf ; - # Two relations allow to define a time interval - # tree:LessThanRelation will be mostly used to recursively go back in time - tree:relation [ a tree:LessThanRelation ; - tree:node ; - tree:path sosa:resultTime ; - tree:value "2020-12-25T15:00:00.000Z"^^xsd:dateTime ; - tree:remainingItems 3 - ], - [ - a tree:GreaterThanOrEqualToRelation ; - tree:node ; - tree:path sosa:resultTime ; - tree:value "2020-12-25T14:00:00.000Z"^^xsd:dateTime ; - tree:remainingItems 3 - ]; - tiles:longitudeTile "8393" ; - tiles:latitudeTile "5467"; - tiles:zoom "14"; - tree:timeQuery "2020-12-25T15:00:00.000Z"^^xsd:dateTime ; # the user requested results that occured after 2020-12-25T15:00:00.000Z - tree:search _:b0 . - - - a tree:Collection ; - tree:view ; - void:subset ; - tree:member _:b1, _:b2 . - -# Specific search form within this tile -_:b0 a hydra:IriTemplate ; - hydra:variableRepresentation hydra:BasicRepresentation ; - hydra:template "https://lodi.ilabt.imec.be/air/14/8393/5467/{t}"; - hydra:mapping [ a hydra:IriTemplateMapping ; - hydra:variable "t" ; - tree:path sosa:resultTime ; - hydra:property tree:timeQuery ; - hydra:required "false"^^xsd:boolean - ] . - -## The latest observations -_:b1 a sosa:Observation; - sosa:resultTime "2020-12-25T15:05:00.000Z"^^xsd:dateTime ; - sosa:hasFeatureOfInterest <#Airquality/lat=51.23759466223419&long=4.415932092815638>, cot:AirQuality ; - sosa:observedProperty cot:NO2 . - -_:b2 a sosa:Observation ; - sosa:resultTime "2020-12-25T15:10:00.000Z"^^xsd:dateTime ; - sosa:hasFeatureOfInterest <#Airquality/lat=51.23759466223419&long=4.415932092815638>, cot:AirQuality ; - sosa:observedProperty cot:PM10 . - -<#Airquality/lat=51.23759466223419&long=4.415932092815638> a sosa:FeatureOfInterest; - rdfs:label "Air quality at this point location"; - geosparql:asWKT "POINT (4.426460266113281 51.24171563651943)"^^geosparql:wktLiteral ; - geo:latitude "51.23759466223419"; - geo:longitude "4.415932092815638". diff --git a/examples/timeseries/airQualityObservations.ttl b/examples/timeseries/airQualityObservations.ttl deleted file mode 100644 index 4a0346f..0000000 --- a/examples/timeseries/airQualityObservations.ttl +++ /dev/null @@ -1,84 +0,0 @@ -@prefix tree: . -@prefix hydra: . -@prefix dcterms: . -@prefix rdfs: . -@prefix lc: . -@prefix xsd: . -@prefix sosa: . -@prefix tiles: . -@prefix geo: . -@prefix cot: . -@prefix sh: . -@prefix geosparql: . -@prefix void: . - - a tree:Node ; - # Let's specify the geospatial boundaries of the root node of a tile - # Option 1: use WKT literal - tree:relation [ - a tree:GeospatiallyContainsRelation ; - tree:path ( sosa:hasFeatureOfInterest geosparql:asWKT ); - tree:node ; - tree:value "POLYGON((4.41650390625 51.248163159055906, 4.41650390625 51.2344073516346, 4.4384765625 51.2344073516346, 4.4384765625 51.248163159055906, 4.41650390625 51.248163159055906))"^^geosparql:wktLiteral - ] ; - # Option 2: use lat long relations - tree:relation [ - a tree:GreaterThanOrEqualToRelation ; - tree:path ( sosa:hasFeatureOfInterest geo:longitude ); - tree:node ; - tree:value "4.41650390625" - ] ; - tree:relation [ - a tree:LessThanOrEqualToRelation ; - tree:path ( sosa:hasFeatureOfInterest geo:longitude ); - tree:node ; - tree:value "4.4384765625" - ] ; - tree:relation [ - a tree:LessThanOrEqualToRelation ; - tree:path ( sosa:hasFeatureOfInterest geo:latitude ); - tree:node ; - tree:value "51.248163159055906" - ] ; - tree:relation [ - a tree:GreaterThanOrEqualToRelation ; - tree:path ( sosa:hasFeatureOfInterest geo:latitude ); - tree:node ; - tree:value "51.2344073516346" - ] ; - tree:search _:b0 . - - a tree:Collection ; - rdfs:label "All airquality observations of our city."@en ; - # Here you can find the root node of the collection - tree:view ; - # (Optional) Point to the root node per tile - void:subset . # This will redirect to the page with the latest sensor data from that tile. In this example, this will redirect to - -_:b0 a hydra:IriTemplate ; - hydra:variableRepresentation hydra:BasicRepresentation ; - hydra:template "https://lodi.ilabt.imec.be/air/{z}/{x}/{y}/{t}"; - hydra:mapping [ - a hydra:IriTemplateMapping ; - hydra:variable "x" ; - hydra:property tiles:longitudeTile ; - hydra:required "true"^^xsd:boolean ; - sh:minInclusive "8393" ; - sh:maxInclusive "8393" - ], [ - a hydra:IriTemplateMapping ; - hydra:variable "y" ; - hydra:property tiles:latitudeTile ; - hydra:required "true"^^xsd:boolean ; - sh:hasValue "5467" - ], [ a hydra:IriTemplateMapping ; - hydra:variable "z" ; - hydra:property tiles:zoom ; - hydra:required "true"^^xsd:boolean ; - sh:hasValue "14" - ], [ a hydra:IriTemplateMapping ; - hydra:variable "t" ; - tree:path sosa:resultTime ; - hydra:property tree:timeQuery ; - hydra:required "false"^^xsd:boolean - ] . \ No newline at end of file