Skip to content

Commit 819eb05

Browse files
committed
Update RDF* mode:
* Eliminate PG mode, `rdfstar` is not boolean valued. * Change CLI from `--rdf-star` to `--rdfstar`. * Update RDF* spec reference. This follows the CG direction to not have modal operation, as annotations (in other serialization formats) more directly handle the PG use case.
1 parent 123cace commit 819eb05

9 files changed

Lines changed: 45 additions & 118 deletions

File tree

README.md

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -246,17 +246,10 @@ By default, the N-Triples reader will reject a document containing a subject res
246246
end
247247
# => RDF::ReaderError
248248

249-
Readers support a `rdfstar` option with either `:PG` (Property Graph) or `:SA` (Separate Assertions) modes. In `:PG` mode, statements that are used in the subject or object positions are also implicitly added to the graph:
249+
Readers support a boolean valued `rdfstar` option.
250250

251251
graph = RDF::Graph.new do |graph|
252-
RDF::NTriples::Reader.new(nt, rdfstar: :PG) {|reader| graph << reader}
253-
end
254-
graph.count #=> 2
255-
256-
When using the `:SA` mode, only one statement is asserted, although the reified statement is contained within the graph.
257-
258-
graph = RDF::Graph.new do |graph|
259-
RDF::NTriples::Reader.new(nt, rdfstar: :SA) {|reader| graph << reader}
252+
RDF::NTriples::Reader.new(nt, rdfstar: true) {|reader| graph << reader}
260253
end
261254
graph.count #=> 1
262255

@@ -478,7 +471,7 @@ see <https://unlicense.org/> or the accompanying {file:UNLICENSE} file.
478471
[RDF::TriX]: https://ruby-rdf.github.com/rdf-trix
479472
[RDF::Turtle]: https://ruby-rdf.github.com/rdf-turtle
480473
[RDF::Raptor]: https://ruby-rdf.github.com/rdf-raptor
481-
[RDF*]: https://lists.w3.org/Archives/Public/public-rdf-star/
474+
[RDF*]: https://w3c.github.io/rdf-star/rdf-star-cg-spec.html/
482475
[LinkedData]: https://ruby-rdf.github.com/linkeddata
483476
[JSON::LD]: https://ruby-rdf.github.com/json-ld
484477
[RestClient]: https://rubygems.org/gems/rest-client

lib/rdf/nquads.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ def read_triple
6969

7070
begin
7171
unless blank? || read_comment
72-
subject = read_uriref || read_node || read_rdfstar || fail_subject
72+
subject = read_uriref || read_node || read_embTriple || fail_subject
7373
predicate = read_uriref(intern: true) || fail_predicate
74-
object = read_uriref || read_node || read_literal || read_rdfstar || fail_object
74+
object = read_uriref || read_node || read_literal || read_embTriple || fail_object
7575
graph_name = read_uriref || read_node
7676
if validate? && !read_eos
7777
log_error("Expected end of statement (found: #{current_line.inspect})", lineno: lineno, exception: RDF::ReaderError)

lib/rdf/ntriples/reader.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ def read_value
213213
begin
214214
read_statement
215215
rescue RDF::ReaderError
216-
value = read_uriref || read_node || read_literal || read_rdfstar
216+
value = read_uriref || read_node || read_literal || read_embTriple
217217
log_recover
218218
value
219219
end
@@ -229,9 +229,9 @@ def read_triple
229229

230230
begin
231231
unless blank? || read_comment
232-
subject = read_uriref || read_node || read_rdfstar || fail_subject
232+
subject = read_uriref || read_node || read_embTriple || fail_subject
233233
predicate = read_uriref(intern: true) || fail_predicate
234-
object = read_uriref || read_node || read_literal || read_rdfstar || fail_object
234+
object = read_uriref || read_node || read_literal || read_embTriple || fail_object
235235

236236
if validate? && !read_eos
237237
log_error("Expected end of statement (found: #{current_line.inspect})", lineno: lineno, exception: RDF::ReaderError)
@@ -247,11 +247,11 @@ def read_triple
247247

248248
##
249249
# @return [RDF::Statement]
250-
def read_rdfstar
250+
def read_embTriple
251251
if @options[:rdfstar] && match(ST_START)
252-
subject = read_uriref || read_node || read_rdfstar || fail_subject
252+
subject = read_uriref || read_node || read_embTriple || fail_subject
253253
predicate = read_uriref(intern: true) || fail_predicate
254-
object = read_uriref || read_node || read_literal || read_rdfstar || fail_object
254+
object = read_uriref || read_node || read_literal || read_embTriple || fail_object
255255
if !match(ST_END)
256256
log_error("Expected end of statement (found: #{current_line.inspect})", lineno: lineno, exception: RDF::ReaderError)
257257
end

lib/rdf/ntriples/writer.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ def format_statement(statement, **options)
227227
# @param [RDF::Statement] statement
228228
# @param [Hash{Symbol => Object}] options ({})
229229
# @return [String]
230-
def format_rdfstar(statement, **options)
230+
def format_embTriple(statement, **options)
231231
"<<%s %s %s>>" % statement.to_a.map { |value| format_term(value, **options) }
232232
end
233233
##

lib/rdf/query.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ def optimize(**options)
255255
# @see RDF::Query::Pattern#cost
256256
# @since 0.3.0
257257
def optimize!(**options)
258-
optional, required = @patterns.partition(&:optional?)
258+
optional, required = @patterns.uniq.partition(&:optional?)
259259
required.sort! do |a, b|
260260
(a.cost || 0) <=> (b.cost || 0)
261261
end

lib/rdf/reader.rb

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,9 @@ def self.options
160160
end,
161161
RDF::CLI::Option.new(
162162
symbol: :rdfstar,
163-
control: :select,
164-
datatype: [:PG, :SA],
165-
on: ["--rdf-star MODE"],
166-
description: "Parse RDF*, either in Property Graph mode (PG) or Separate Assertions mode (SA).") {|arg| arg.to_sym},
163+
datatype: TrueClass,
164+
on: ["--rdfstar"],
165+
description: "Parse RDF*."),
167166
RDF::CLI::Option.new(
168167
symbol: :validate,
169168
datatype: TrueClass,
@@ -276,10 +275,8 @@ def to_sym
276275
# the encoding of the input stream
277276
# @param [Boolean] intern (true)
278277
# whether to intern all parsed URIs
279-
# @param [:PG, :SA] rdfstar (nil)
278+
# @param [Boolean] rdfstar (false)
280279
# support parsing RDF* statement resources.
281-
# If `:PG`, referenced statements are also emitted.
282-
# If `:SA`, referenced statements are not emitted.
283280
# @param [Hash] prefixes (Hash.new)
284281
# the prefix mappings to use (not supported by all readers)
285282
# @param [Hash{Symbol => Object}] options
@@ -295,7 +292,7 @@ def initialize(input = $stdin,
295292
encoding: Encoding::UTF_8,
296293
intern: true,
297294
prefixes: Hash.new,
298-
rdfstar: nil,
295+
rdfstar: false,
299296
validate: false,
300297
**options,
301298
&block)
@@ -401,9 +398,6 @@ def prefix(name, uri = nil)
401398
# Statements are yielded in the order that they are read from the input
402399
# stream.
403400
#
404-
# If the `rdfstar` option is `:PG` and triples include
405-
# embedded statements, they are also enumerated.
406-
#
407401
# @overload each_statement
408402
# @yield [statement]
409403
# each statement
@@ -423,7 +417,6 @@ def each_statement(&block)
423417
loop do
424418
st = read_statement
425419
block.call(st)
426-
each_pg_statement(st, &block) if options[:rdfstar] == :PG
427420
end
428421
rescue EOFError
429422
rewind rescue nil
@@ -441,9 +434,6 @@ def each_statement(&block)
441434
# Triples are yielded in the order that they are read from the input
442435
# stream.
443436
#
444-
# If the `rdfstar` option is `:PG` and triples include
445-
# embedded statements, they are also enumerated.
446-
#
447437
# @overload each_triple
448438
# @yield [subject, predicate, object]
449439
# each triple
@@ -464,10 +454,6 @@ def each_triple(&block)
464454
loop do
465455
triple = read_triple
466456
block.call(*triple)
467-
if options[:rdfstar] == :PG
468-
block.call(*triple[0].to_a) if triple[0].is_a?(Statement)
469-
block.call(*triple[2].to_a) if triple[2].is_a?(Statement)
470-
end
471457
end
472458
rescue EOFError
473459
rewind rescue nil

lib/rdf/writer.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ def format_term(term, **options)
516516
when RDF::Literal then format_literal(term, **options)
517517
when RDF::URI then format_uri(term, **options)
518518
when RDF::Node then format_node(term, **options)
519-
when RDF::Statement then format_rdfstar(term, **options)
519+
when RDF::Statement then format_embTriple(term, **options)
520520
else nil
521521
end
522522
end
@@ -574,7 +574,7 @@ def format_list(value, **options)
574574
# @return [String]
575575
# @raise [NotImplementedError] unless implemented in subclass
576576
# @abstract
577-
def format_rdfstar(value, **options)
577+
def format_embTriple(value, **options)
578578
raise NotImplementedError.new("#{self.class}#format_statement") # override in subclasses
579579
end
580580

spec/nquads_spec.rb

Lines changed: 12 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -205,45 +205,21 @@
205205
end
206206
end
207207

208-
context "in property graph mode" do
209-
statements.each do |name, st|
210-
context name do
211-
let(:graph) {RDF::Graph.new << RDF::NQuads::Reader.new(st, rdfstar: :PG)}
208+
statements.each do |name, st|
209+
context name do
210+
let(:graph) {RDF::Graph.new << RDF::NQuads::Reader.new(st, rdfstar: true)}
212211

213-
it "creates two statements" do
214-
expect(graph.count).to eql(2)
215-
end
216-
217-
it "has a statement whose subject or object is a statement" do
218-
referencing = graph.statements.detect {|s| s.predicate == RDF::URI("http://example/p")}
219-
expect(referencing).to be_a_statement
220-
if referencing.subject.statement?
221-
expect(referencing.subject).to be_a_statement
222-
else
223-
expect(referencing.object).to be_a_statement
224-
end
225-
end
212+
it "creates two statements" do
213+
expect(graph.count).to eql(1)
226214
end
227-
end
228-
end
229-
230-
context "in separate assertions mode" do
231-
statements.each do |name, st|
232-
context name do
233-
let(:graph) {RDF::Graph.new << RDF::NQuads::Reader.new(st, rdfstar: :SA)}
234-
235-
it "creates two statements" do
236-
expect(graph.count).to eql(1)
237-
end
238215

239-
it "has a statement whose subject or object is a statement" do
240-
referencing = graph.statements.first
241-
expect(referencing).to be_a_statement
242-
if referencing.subject.statement?
243-
expect(referencing.subject).to be_a_statement
244-
else
245-
expect(referencing.object).to be_a_statement
246-
end
216+
it "has a statement whose subject or object is a statement" do
217+
referencing = graph.statements.first
218+
expect(referencing).to be_a_statement
219+
if referencing.subject.statement?
220+
expect(referencing.subject).to be_a_statement
221+
else
222+
expect(referencing.object).to be_a_statement
247223
end
248224
end
249225
end

spec/ntriples_spec.rb

Lines changed: 13 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -428,49 +428,21 @@
428428
end
429429
end
430430

431-
context "in property graph mode" do
432-
statements.each do |name, st|
433-
context name do
434-
let(:graph) {parse(st, rdfstar: :PG)}
435-
436-
it "creates two statements" do
437-
expect(graph.count).to eql(2)
438-
end unless name.to_s.include?('recursive')
439-
440-
it "creates multiple statements" do
441-
expect(graph.count).to be > 2
442-
end if name.to_s.include?('recursive')
443-
444-
it "has a statement whose subject or object is a statement" do
445-
referencing = graph.statements.detect {|s| s.predicate == RDF::URI("http://example/p")}
446-
expect(referencing).to be_a_statement
447-
if referencing.subject.statement?
448-
expect(referencing.subject).to be_a_statement
449-
else
450-
expect(referencing.object).to be_a_statement
451-
end
452-
end
453-
end
454-
end
455-
end
431+
statements.each do |name, st|
432+
context name do
433+
let(:graph) {parse(st, rdfstar: true)}
456434

457-
context "in separate assertions mode" do
458-
statements.each do |name, st|
459-
context name do
460-
let(:graph) {parse(st, rdfstar: :SA)}
461-
462-
it "creates two statements" do
463-
expect(graph.count).to eql(1)
464-
end
435+
it "creates two statements" do
436+
expect(graph.count).to eql(1)
437+
end
465438

466-
it "has a statement whose subject or object is a statement" do
467-
referencing = graph.statements.first
468-
expect(referencing).to be_a_statement
469-
if referencing.subject.statement?
470-
expect(referencing.subject).to be_a_statement
471-
else
472-
expect(referencing.object).to be_a_statement
473-
end
439+
it "has a statement whose subject or object is a statement" do
440+
referencing = graph.statements.first
441+
expect(referencing).to be_a_statement
442+
if referencing.subject.statement?
443+
expect(referencing.subject).to be_a_statement
444+
else
445+
expect(referencing.object).to be_a_statement
474446
end
475447
end
476448
end

0 commit comments

Comments
 (0)