Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add section about 'unstar' mapping #115

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
5 changes: 5 additions & 0 deletions spec/ex-classicize-input.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX ex: <http://example.org/>

<< ex:s ex:p ex:o >> ex:q "some value".

5 changes: 5 additions & 0 deletions spec/ex-classicize-input2.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX ex: <http://example.org/>

_:r1 rdf:reifies <<( ex:s ex:p ex:o )>>.
_:r1 ex:q "some value".
11 changes: 11 additions & 0 deletions spec/ex-classicize-output.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX ex: <http://example.org/>

_:r1 rdf:reifies _:gen1.
_:r1 ex:q "some value".

_:gen1 a rdf:TripleTerm ;
rdf:ttSubject ex:s;
rdf:ttPredicate ex:p;
rdf:ttObject ex:o.

262 changes: 259 additions & 3 deletions spec/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
github: "https://github.com/w3c/rdf-concepts/",
group: "rdf-star",
doJsonLd: true,
wgPublicList: "public-rdf-star-wg"
wgPublicList: "public-rdf-star-wg",
maxTocLevel: 2,
};
</script>
<style>
Expand All @@ -49,6 +50,19 @@
.grammar-literal { color: gray;}
code {color: #ff4500;} /* Old W3C Style */
div.abnf {margin-left: 1em;}

.algorithm ol {
counter-reset: numsection;
list-style-type: none;
}
.algorithm ol>li {
margin: 0.5em 0;
}
.algorithm ol>li:before {
font-weight: bold;
counter-increment: numsection;
content: counters(numsection, ".") ") ";
}
</style>
</head>

Expand Down Expand Up @@ -498,12 +512,12 @@ <h3>RDF Documents and Syntaxes</h3>
<p>This specification establishes two conformance levels:</p>

<ul>
<li><dfn class="no-export lint-ignore">Full conformance</dfn>
<li><dfn class="no-export lint-ignore" data-lt="full">Full conformance</dfn>
supports <a data-lt="RDF graph">graphs</a> and <a data-lt="RDF dataset">datasets</a>
with <a>triples</a> that contain <a>triple terms</a>.
Concrete syntaxes in which such graphs and datasets can be expressed include
[[RDF12-N-TRIPLES]], [[RDF12-N-QUADS]], [[RDF12-TURTLE]], and [[RDF12-TRIG]].</li>
<li><dfn class="no-export lint-ignore">Classic conformance</dfn>
<li><dfn class="no-export lint-ignore" data-lt="classic">Classic conformance</dfn>
only supports <a data-lt="RDF graph">graphs</a> or <a data-lt="RDF dataset">datasets</a>
with <a>triples</a> that do not contain <a>triple terms</a>.</li>
</ul>
Expand Down Expand Up @@ -875,6 +889,12 @@ <h3>Triple Terms</h3>
Every <a>triple</a> whose <a>object</a> is not a <a>triple term</a> SHOULD NOT
use <code>http://www.w3.org/1999/02/22-rdf-syntax-ns#reifies</code> (<code>rdf:reifies</code>)
as its <a>predicate</a>.</p>

<p>The <dfn data-lt="constituent">constituent terms</dfn> (or simply constituents)
of a [=triple term=] (resp. an [=RDF triple=]) are its [=subject=], its [=predicate=], its [=object=],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resp.? This expands in my head to respectively (and minimally requires a following comma, in every instance), but I don't know what the respective reference is.

Abbreviations like this should generally be avoided, especially when, as here, their meaning might be at all confusing.

and all the [=constituent terms=] of its [=object=] if it is itself a [=triple term=].
By extension, the [=constituent terms=] of an [=RDF graph=] are all the constituent terms of its triples.
</p>
</section>

<section id="section-text-direction" class="informative">
Expand Down Expand Up @@ -1450,6 +1470,242 @@ <h2>Generalizations of RDF Triples, Graphs, and Datasets</h2>
</section>


<section id="section-classic-full-interop" class="informative">
<h2>Interoperability between RDF [=Classic=] and RDF [=Full=]</h2>

<p class=issue>Should we make this section normative?</p>

<p>This section provides transformations between [=Full=] [=RDF graphs=] (resp. [=RDF datasets=]) and [=Classic=] [=RDF graphs=] (resp. [=RDF datasets=]),
to provide some level of interoperability between the different classes of <a href="#conformance">Conformance</a>.

<p class=issue>Should we go even further and aim to provide interoperability between <em>RDF 1.1</em> and RDF 1.2 [=Full=]?</p>

<p class=issue>AT RISK: the working group may decide to replace the terms `rdf:TripleTerm`, `rdf:ttSubject`, `rdf:ttPredicate` and `rdf:ttObject` used in this section by other terms, possibly in a different namespace.</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<p class=issue>AT RISK: the working group may decide to replace the terms `rdf:TripleTerm`, `rdf:ttSubject`, `rdf:ttPredicate` and `rdf:ttObject` used in this section by other terms, possibly in a different namespace.</p>
<p class=issue>AT RISK: The Working Group may decide to replace the terms `rdf:TripleTerm`, `rdf:ttSubject`, `rdf:ttPredicate`, and `rdf:ttObject` used in this section with other terms, possibly in a different namespace.</p>


<p>These transformation are designed to be:</p>

<dl>
<dt>Information preserving</dt>
<dd>It must be possible to reconstruct the input graph (resp. dataset) from the output graph (resp. dataset).
Note that, on the other hand, these transformations are not designed to be semantics preserving:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Note that, on the other hand, these transformations are not designed to be semantics preserving:
Note, however, that these transformations are not designed to preserve semantics:

the output graph is not semantically [=equivalent=] to the input graph,
at least not in the entailment regimes defined in [[RDF12-SEMANTICS]].
</dd>
<dt>Idempotent</dt>
<dd>Applying a transformation several times to a graph (resp. dataset) should have the same effect as applying it once.
Moreover, [=classicizing=] a graph (resp. dataset) that is already complying with RDF [=Classic=] (i.e. containing no [=triple term=]) must result in the same graph (resp. dataset).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we will be well served by using RDF Classic as the defined term, rather than just Classic. I'm not making that change here; only suggesting it to you.

Suggested change
Moreover, [=classicizing=] a graph (resp. dataset) that is already complying with RDF [=Classic=] (i.e. containing no [=triple term=]) must result in the same graph (resp. dataset).
Moreover, [=classicizing=] a graph (resp. dataset) that is already complying with RDF [=Classic=] (i.e., containing no [=triple term=]) must result in the same graph (resp. dataset).

</dd>
<dt>Universal</dt>
<dd>It should be possible to transform any [=Full=] graph (resp. dataset) to a [=Classic=] graph (resp. dataset) using this method.
There is actually <a href="#section-classicize-caveat">a minor caveat</a> to this property.
Comment on lines +1499 to +1500
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<dd>It should be possible to transform any [=Full=] graph (resp. dataset) to a [=Classic=] graph (resp. dataset) using this method.
There is actually <a href="#section-classicize-caveat">a minor caveat</a> to this property.
<dd>It should be possible (with <a href="#section-classicize-caveat">a minor caveat</a>) to transform any [=Full=] graph (resp. dataset) to a [=Classic=] graph (resp. dataset) using this method.

</dd>
</dl>

<section id="section-classicize-definition">
<h2>From [=Full=] to [=Classic=]</h2>

<p>
Encoding an [=RDF graph=] to ensure that it is consumable by an RDF [=Classic=] implementation is called <dfn data-lt="classicize|classicized">classicizing</dfn> it.
It consists, while the graph has a [=triple term=] <var>tt</var> in its [=constituent terms=], in minting a fresh [=blank node=] <var>b</var>
(i.e. a blank node not in use in the graph), and replace <var>tt</var> with <var>b</var> in all the triples of the graph having <var>tt</var> in their [=constituents=].
Then the following triples are added to the graph (where <var>s</var>, <var>p</var> and <var>o</var> are respectively the [=subject=], [=predicate=] and [=object=] of <var>tt</var>):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section is written considering that graphs are mutable (add or remove something to a graph), while we define a graph as being static:

The RDF data model is atemporal: RDF graphs are static snapshots of information.

Would it not be cleaner to describe the creation of a new graph after applying such transformations to make these operations more functional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section is written considering that graphs are mutable (add or remove something to a graph), while we define a graph as being static

Yes, I agree that could be confusing, but there are precedents of speaking of "replacing" nodes in a graph (sec 3.7 and 3.8). And I think that this is a concise and intuitive way to convey what the transformation is.

Note that the algorithm, on the other hand assumes immutable graphs and produces a new graph from scratch.

Comment on lines +1509 to +1511
Copy link
Member

@TallTed TallTed Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
It consists, while the graph has a [=triple term=] <var>tt</var> in its [=constituent terms=], in minting a fresh [=blank node=] <var>b</var>
(i.e. a blank node not in use in the graph), and replace <var>tt</var> with <var>b</var> in all the triples of the graph having <var>tt</var> in their [=constituents=].
Then the following triples are added to the graph (where <var>s</var>, <var>p</var> and <var>o</var> are respectively the [=subject=], [=predicate=] and [=object=] of <var>tt</var>):
[=Classicizing=] consists of repeating the following steps until no [=constituent=] of the graph is a [=triple term=], and the graph is therefore compliant with RDF [=Classic=]: while the graph has a [=triple term=] <var>tt</var> in its [=constituent terms=], of minting a fresh [=blank node=] <var>b</var>
(i.e., a blank node not yet in use in the graph); replacing each <var>tt</var> with <var>b</var> in all the triples of the graph having <var>tt</var> in their [=constituents=];
and then adding the following triples to the graph (where <var>s</var>, <var>p</var>, and <var>o</var> are respectively the [=subject=], [=predicate=] and [=object=] of <var>tt</var>):

</p>
<ul>
<li>(<var>b</var>, `rdf:type`, `rdf:TripleTerm`)
<li>(<var>b</var>, `rdf:ttSubject`, <var>s</var>)
<li>(<var>b</var>, `rdf:ttPredicate`, <var>p</var>)
<li>(<var>b</var>, `rdf:ttObject`, <var>o</var>)
</ul>
<p>This process is repeated until the graph has no [=triple term=] [=constituent=], and is therefore compliant with RDF [=Classic=].</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've moved this sentence into the introductory sentence, above.

Suggested change
<p>This process is repeated until the graph has no [=triple term=] [=constituent=], and is therefore compliant with RDF [=Classic=].</p>


<p>Note that this transformation is <em>information preserving</em> only when the input graph does not contain at the same time a [=triple term=]
and an [=asserted=] triple (<var>b</var>, `rdf:type`, `rdf:TripleTerm`) where <var>b</var> is a [=blank node=].
Implementations encountering this situation MUST report an error.
See Section <a href="#section-classicize-caveat"></a> for a discussion on this limitation.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
See Section <a href="#section-classicize-caveat"></a> for a discussion on this limitation.
This limitation is discussed in Section <a href="#section-classicize-caveat"></a>.

</p>

<p class=note>The blank nodes generated to replace [=triple terms=] should not be confused with the [=reifiers=] that are typically associated to these [=triple terms=].</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to link this to the discussion of those "typical associations".

Suggested change
<p class=note>The blank nodes generated to replace [=triple terms=] should not be confused with the [=reifiers=] that are typically associated to these [=triple terms=].</p>
<p class=note>The blank nodes generated to replace [=triple terms=] should not be confused with the [=reifiers=] that are typically associated with these [=triple terms=].</p>


<p>
[=Classicizing=] an [=RDF dataset=] consists in [=classicizing=] its [=default graph=] and each of its [=named graph=].
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[=Classicizing=] an [=RDF dataset=] consists in [=classicizing=] its [=default graph=] and each of its [=named graph=].
[=Classicizing=] an [=RDF dataset=] consists of [=classicizing=] its [=default graph=] and each of its [=named graph=].

In this case, the fresh [=blank node=] assigned to each [=triple term=] must not be used in any graph of the dataset.
</p>

<p>
See Section <a href="#section-classicize-algo"></a> for a detailed algorithm of the transformation.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
See Section <a href="#section-classicize-algo"></a> for a detailed algorithm of the transformation.
A detailed algorithm of the transformation is found in Section <a href="#section-classicize-algo"></a>.

</p>

<section id="section-classicize-example">
<h2>Example</h2>

<p>The examples in this section are using the Turtle concrete syntax [[RDF12-TURTLE]].</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<p>The examples in this section are using the Turtle concrete syntax [[RDF12-TURTLE]].</p>
<p>The examples in this section are expressed in the Turtle concrete syntax [[RDF12-TURTLE]].</p>


<pre id="ex-classicize-input"
class="example nohighlight"
title="An input Full RDF graph"
data-include="./ex-classicize-input.ttl"
data-include-format="text"
></pre>

<pre id="ex-classicize-input2"
class="example nohighlight"
title="The same graph as above, with reifiers made explicit"
data-include="./ex-classicize-input2.ttl"
data-include-format="text"
></pre>

<pre id="ex-classicize-output"
class="example nohighlight"
title="The result of classicizing the dataset above"
data-include="./ex-classicize-output.ttl"
data-include-format="text"
></pre>

</section>

</section>

<section id="section-unclassicize-definition">
<h2>From [=Classic=] to [=Full=]</h2>

<p>Reverting a [=classicize=] graph to its original form consists,
for each [=blank node=] <var>b</var> that is the subject of an [=asserted=] triple (<var>b</var>, `rdf:type`, `rdf:TripleTerm`),
in locating the three other [=asserted=] triples (<var>b</var>, `rdf:ttSubject`, <var>s</var>),
(<var>b</var>, `rdf:ttPredicate`, <var>p</var>),
and (<var>b</var>, `rdf:ttObject`, <var>o</var>).
These four triples are removed from the graph.
All remaining occurrences of <var>b</var> as a [=constituent term=] of the graph are then replaced with the triple term (<var>s</var>, <var>p</var>, <var>o</var>).
Comment on lines +1571 to +1577
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<p>Reverting a [=classicize=] graph to its original form consists,
for each [=blank node=] <var>b</var> that is the subject of an [=asserted=] triple (<var>b</var>, `rdf:type`, `rdf:TripleTerm`),
in locating the three other [=asserted=] triples (<var>b</var>, `rdf:ttSubject`, <var>s</var>),
(<var>b</var>, `rdf:ttPredicate`, <var>p</var>),
and (<var>b</var>, `rdf:ttObject`, <var>o</var>).
These four triples are removed from the graph.
All remaining occurrences of <var>b</var> as a [=constituent term=] of the graph are then replaced with the triple term (<var>s</var>, <var>p</var>, <var>o</var>).
<p>Reverting a [=classicized=] graph to its original form consists of locating
each [=asserted=] triple (<var>b</var>, `rdf:type`, `rdf:TripleTerm`)
that has a [=blank node=] <var>b</var> as its subject,
along with the three associated [=asserted=] triples
that have the same [=blank node=] <var>b</var> as their subjects, i.e.,
(<var>b</var>, `rdf:ttSubject`, <var>s</var>),
(<var>b</var>, `rdf:ttPredicate`, <var>p</var>),
and (<var>b</var>, `rdf:ttObject`, <var>o</var>);
removing these four triples from the graph;
and replacing all remaining occurrences of <var>b</var>
as a [=constituent term=] of the graph
with the triple term (<var>s</var>, <var>p</var>, <var>o</var>).

</p>

<p>Implementations MUST report an error if, for a given <var>b</var>,
it can not unambiguously determine <var>s</var>, <var>p</var> or <var>o</var>
(i.e. if one of the `classicize:` properties of <var>b</var> is missing or duplicated).
Implementations MUST also report an error if the input graph contains at the same time a [=triple term=] and an [=asserted triple=] (<var>b</var>, `rdf:type`, `rdf:TripleTerm`) where <var>b</var> is a [=blank node=].
None of these situations can occur if the input graph was produced by the [=classicize=] transformation.
Comment on lines +1580 to +1584
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<p>Implementations MUST report an error if, for a given <var>b</var>,
it can not unambiguously determine <var>s</var>, <var>p</var> or <var>o</var>
(i.e. if one of the `classicize:` properties of <var>b</var> is missing or duplicated).
Implementations MUST also report an error if the input graph contains at the same time a [=triple term=] and an [=asserted triple=] (<var>b</var>, `rdf:type`, `rdf:TripleTerm`) where <var>b</var> is a [=blank node=].
None of these situations can occur if the input graph was produced by the [=classicize=] transformation.
<p>An implementation MUST report an error if, for a given <var>b</var>,
it can not unambiguously determine <var>s</var>, <var>p</var>, or <var>o</var>
(i.e., if one of the `classicize:` properties
— `rdf:ttSubject`, `rdf:ttPredicate`, or `rdf:ttObject` —
of <var>b</var> is missing or duplicated).
An implementation MUST also report an error if the input graph contains
at the same time a [=triple term=] and an [=asserted triple=]
(<var>b</var>, `rdf:type`, `rdf:TripleTerm`)
where <var>b</var> is the same [=blank node=].
Note that none of these situations can occur if the input graph was produced by the [=classicize=] transformation.

</p>

<p>To revert a [=classicized=] [=RDF dataset=] to its original form, the transformation above is applied to its [=default graph=] and to each of its [=named graphs=].
</p>

<p>Note that this transformation has no effect on any [=RDF graph=] or [=RDF dataset=] that does not use the `rdf:TripleTerm` type,
including [=Full=] graphs or datasets containing [=triple terms=].
This makes this transformation <em>idempotent</em> as intended.
</p>
</section>

<section id="section-classicize-caveat">
<h2>Limitations</h2>

<p>The two transformations above are explicitly not supporting graphs or datasets containing at the same time a [=triple term=]
and an [=asserted triple=] (<var>b</var>, `rdf:type`, `rdf:TripleTerm`) where <var>b</var> is a [=blank node=].
This means, in particular, that the [=classicize=] transformation is not strictly <em>universal</em>.
Comment on lines +1599 to +1601
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<p>The two transformations above are explicitly not supporting graphs or datasets containing at the same time a [=triple term=]
and an [=asserted triple=] (<var>b</var>, `rdf:type`, `rdf:TripleTerm`) where <var>b</var> is a [=blank node=].
This means, in particular, that the [=classicize=] transformation is not strictly <em>universal</em>.
<p>The two transformations above explicitly do not support graphs or datasets containing at the same time a [=triple term=] and an [=asserted triple=]
(<var>b</var>, `rdf:type`, `rdf:TripleTerm`)
where <var>b</var> is the same [=blank node=].
This means that the [=classicize=] transformation is not <em>strictly</em> universal.

</p>

<p>This limitation should not be an issue in practice.
The `rdf:TripleTerm` type is unlikely to be in used in any published graph or dataset,
as it was not defined prior to this specification.
For this reason, using it would actually have been bad practice.
As for future graphs and datasets, their authors should consider this type to be reserved, in order to prevent interference with the [=classicize=] transformation.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
As for future graphs and datasets, their authors should consider this type to be reserved, in order to prevent interference with the [=classicize=] transformation.
For future graphs and datasets, this type should be considered to be reserved for use within the [=classicize=] transformation, and not used otherwise.

</p>

<p class=note>
This is one of the reasons why this transformation introduces a new vocabulary
(`rdf:TripleTerm`, `rdf:ttSubject`, `rdf:ttPredicate`, `rdf::ttObject`),
rather than repurposing the existing <a data-cite="RDF12-SCHEMA#ch_reificationvocab">reification vocabulary</a>
(`rdf:Statement`, `rdf:subject`, `rdf:predicate`, `rdf:object`).
Contrarily to `rdf:TripleTerm`, `rdf:Statement` is known to used in widely used datasets (e.g. <a href="https://www.uniprot.org/">Uniprot</a>),
so deprecating its usage as "reserved" was not an option.
Comment on lines +1612 to +1617
Copy link
Member

@TallTed TallTed Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to find another example or two, to go with Uniprot.

Suggested change
This is one of the reasons why this transformation introduces a new vocabulary
(`rdf:TripleTerm`, `rdf:ttSubject`, `rdf:ttPredicate`, `rdf::ttObject`),
rather than repurposing the existing <a data-cite="RDF12-SCHEMA#ch_reificationvocab">reification vocabulary</a>
(`rdf:Statement`, `rdf:subject`, `rdf:predicate`, `rdf:object`).
Contrarily to `rdf:TripleTerm`, `rdf:Statement` is known to used in widely used datasets (e.g. <a href="https://www.uniprot.org/">Uniprot</a>),
so deprecating its usage as "reserved" was not an option.
This is one reason why this transformation introduces new vocabulary terms
(`rdf:TripleTerm`, `rdf:ttSubject`, `rdf:ttPredicate`, `rdf::ttObject`),
rather than repurposing the existing <a data-cite="RDF12-SCHEMA#ch_reificationvocab">reification vocabulary</a>
(`rdf:Statement`, `rdf:subject`, `rdf:predicate`, `rdf:object`).
Unlike `rdf:TripleTerm`, `rdf:Statement` is known to be found in
widely used datasets (e.g., <a href="https://www.uniprot.org/">Uniprot</a>),
so reserving its use for the [=classicize=] transformation was not an option.

</p>

<p>Another consequence of this restriction is that users should be careful when merging graphs in an application that [=classicize=] graphs or datasets.
More precisely, merging a [=Full=] [=RDF graph=] (containing at least one [=triple term=])
with a [=classicized=] [=RDF graph=] (and therefore potentially containing [=blank node=] instances of `rdf:TripleTerm`)
could result in a "hybrid" graph that can not be transformed.
Such applications should make sure to [=classicize=] every graph prior to merging them.
Conversely, applications supporting RDF [=Full=] should make sure to apply the reverse tranformation to any graph that is known or likely to be [=classicized=],
to avoid creating such "hybrid" graphs.
Since these transformations are <em>idempotent</em>, there is no harm in applying them more than necessary.
Comment on lines +1620 to +1627
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its troubling that this caution was written to users and then later, to applications, rather than implementers who ought to bear the burden. Further editing will be good. Also, this segment --

      Therefor, such applications should [=classicize=] every graph prior to merging them.
      Conversely, applications supporting RDF [=Full=] should make sure to apply the reverse transformation
      to any graph that is known or likely to have been [=classicized=],
      to avoid creating such "hybrid" graphs.

— would benefit from rewriting to make it a single caution that covers both [=Classic=] applications classicizing, and [=Full=] applications "de-classicing" (there must be a better word! "the reverse transformation" doesn't cut it...), every graph

Suggested change
<p>Another consequence of this restriction is that users should be careful when merging graphs in an application that [=classicize=] graphs or datasets.
More precisely, merging a [=Full=] [=RDF graph=] (containing at least one [=triple term=])
with a [=classicized=] [=RDF graph=] (and therefore potentially containing [=blank node=] instances of `rdf:TripleTerm`)
could result in a "hybrid" graph that can not be transformed.
Such applications should make sure to [=classicize=] every graph prior to merging them.
Conversely, applications supporting RDF [=Full=] should make sure to apply the reverse tranformation to any graph that is known or likely to be [=classicized=],
to avoid creating such "hybrid" graphs.
Since these transformations are <em>idempotent</em>, there is no harm in applying them more than necessary.
<p>Another consequence of this restriction is that users will need to be aware and careful when merging graphs in an application that [=classicizes=] graphs or datasets.
The concern is that merging a [=Full=] [=RDF graph=] containing at least one [=triple term=]
with a [=classicized=] [=RDF graph=] (which might contain [=blank node=] instances of `rdf:TripleTerm`)
could result in a "hybrid" graph that cannot be transformed to a consistent [=Full=] nor [=Classic=] [=RDF graph=].
Therefor, such applications should [=classicize=] every graph prior to merging them.
Conversely, applications supporting RDF [=Full=] should make sure to apply the reverse transformation
to any graph that is known or likely to have been [=classicized=],
to avoid creating such "hybrid" graphs.
Since these transformations are designed to be <em>idempotent</em>, there is no harm in applying them more than necessary.

</p>
</section>

<section>
<h2>Algorithms</h2>

<section id="section-classicize-algo" class="algorithm">
<h2>The `classicize` algorithm</h2>

<p>The algorithm expects one input variable <var>Gᵢ</var> which is an [=RDF graph=]. It returns a [=Classic=] [=RDF graph=].
</p>

<ol>
<li>Let <var>Gₒ</var> be an empty [=RDF graph=].</li>
<li>Let <var>M</var> be an empty map from [=triple terms=] to [=blank nodes=].</li>
<li>Let <var>inputKind</var> be `null`.</li>
<li>For each triple (<var>s</var>, <var>p</var>, <var>o</var>) in <var>Gᵢ</var>:<ol>
<li>If <var>s</var> is a [=blank node=], <var>p</var> is `rdf:type` and <var>o</var> is `rdf:TripleTerm`, then:<ol>
<li id="classicize-error1">If <var>inputKind</var> is `"full"` then exit with an error.</li>
<li>Otherwise, set <var>inputKind</var> to `"classic"`.</li>
</ol></li>
<li>If <var>o</var> is a [=triple term=], then:<ol>
<li id="classicize-error2">If <var>inputKind</var> is `"classic"` then exit with an error.</li>
<li>Otherwise, set <var>inputKind</var> to `"full"`.</li>
<li>Let <var>b</var>, <var>M'</var> and <var>G'</var> be the result of invoking <a href="#section-ctt-algo">`classicize-triple-term`</a> passing <var>o</var> as <var>t</var> and <var>M</var> as <var>Mi</var>.</li>
<li>Merge <var>M'</var> into <var>M</var>.
<li>Merge <var>G'</var> into <var>Gₒ</var>.
<li>Set <var>o</var> to <var>b</var>.
</ol></li>
<li>Add the triple (<var>s</var>, <var>p</var>, <var>o</var>) to <var>Gₒ</var>.</li>
</ol></li>
<li>Return <var>Gₒ</var>.</li>
</ol>
</section>

<section id="section-ctt-algo" class="algorithm">
<h2>The `classicize-triple-term` algorithm</h2>

<p>This algorithm is responsible for incrementally populating the mapping <var>M</var> and the graph <var>G</var> used internally by the <a href="#section-classicize-algo">`classicize`</a> algorithm. It receives a [=triple term=] as input and processes it recursively (in case its object is itself a [=triple term=]). It returns, among other things, the [=blank node=] minted to replace the [=triple term=] in the transformed [=Classic=] [=RDF graph=].</p>

<p>This algorithm expects two input variables:
a [=triple term=] <var>t</var>,
and a map <var>Mᵢ</var> from [=triple terms=] to [=blank nodes=].
It returns a [=blank node=] <var>b</var>,
a map <var>Mₒ</var> from [=triple terms=] to [=blank nodes=],
and a [=Classic=] [=RDF graph=] <var>G</var>.
</p>

<ol>
<li>Let <var>Mₒ</var> be an empty map.</li>
<li>Let <var>G</var> be an empty [=RDF graph=].</li>
<li>Let <var>b</var> be the [=blank node=] associated with <var>t</var> in <var>Mᵢ</var>, if any.
<li>Otherwise:<ol>
<li>Let <var>s</var>, <var>p</var> and <var>o</var> be the subject, predicate and object of <var>t</var>, respectively.</li>
<li>If <var>o</var> is a [=triple term=], then:<ol>
<li>Let <var>b'</var>, <var>M'</var> and <var>G'</var> be the result of invoking <a href="#section-ctt-algo">`classicize-triple-term`</a> passing <var>o</var> as <var>t</var> and <var>Mᵢ</var>.</li>
<li>Set <var>o</var> to <var>b'</var>.
<li>Merge <var>M'</var> into <var>Mₒ</var>.
<li>Merge <var>G'</var> into <var>G</var>.
</ol></li>
<li id="qtt-fresh-bnode">Let <var>b</var> be a fresh blank node.</li>
<li>Add the association (<var>t</var>, <var>b</var>) to <var>Mₒ</var>.</li>
<li>Add the triples (<var>b</var>, `rdf:type`, `rdf:TripleTerm`), (<var>b</var>, `rdf:ttSubject`, <var>s</var>), (<var>b</var>, `rdf:ttPredicate`, <var>p</var>), and (<var>b</var>, `rdf:ttObject`, <var>o</var>) in <var>G</var>.</li>
</ol></li>
<li>Return <var>b</var>, <var>Mₒ</var> and <var>G</var>.</li>
</ol>

</section>

<section id="section-unclassicize-algo" class="algorithm">
<h2>The `revert-classicize` algorithm</h2>

<p class=issue>Write this algorithm</p>
</section>


</section>


</section>

<section id="section-additional-datatypes" class="appendix">
<h2>Additional Datatypes</h2>
<p>This section defines additional <a>datatypes</a> that RDF processors MAY support.</p>
Expand Down
Loading