rdf-n3 3.1.2 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +14 -15
- data/VERSION +1 -1
- data/lib/rdf/n3/algebra/list/iterate.rb +96 -0
- data/lib/rdf/n3/algebra/list_operator.rb +13 -0
- data/lib/rdf/n3/algebra/log/dtlit.rb +41 -0
- data/lib/rdf/n3/algebra/log/langlit.rb +41 -0
- data/lib/rdf/n3/algebra/resource_operator.rb +0 -1
- data/lib/rdf/n3/algebra.rb +6 -0
- data/lib/rdf/n3/extensions.rb +2 -2
- data/lib/rdf/n3/reader.rb +7 -72
- data/lib/rdf/n3/terminals.rb +0 -2
- data/lib/rdf/n3/writer.rb +17 -26
- metadata +25 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c5082274015223c285074d961b1de134d76a9e4b4174ec70cabb326161609ec8
|
4
|
+
data.tar.gz: a8df856b348d43664a99d1ce183da15082cb803b271eafd6f98abf3b8ac2f0eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 561febe8dde9ad892eab9eda2cdf957c1d79c350be900a35c487ee6d3362c780aa5eee9868ba07c2c66d201f4f2a16a5bb0bb7853c366d2ab9b1593e50b25b0b
|
7
|
+
data.tar.gz: c15291bf10df5b98eb5f02f859b2c5d00d25b145f9effcf7c256b6a0d2edce32b1a66e9254308d6674131a84322fa33068bb9c661236b8c1ee26468ca26ee8fc
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@ Notation-3 reader/writer for [RDF.rb][RDF.rb] .
|
|
3
3
|
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/rdf-n3.png)](https://badge.fury.io/rb/rdf-n3)
|
5
5
|
[![Build Status](https://github.com/ruby-rdf/rdf-n3/workflows/CI/badge.svg?branch=develop)](https://github.com/ruby-rdf/rdf-n3/actions?query=workflow%3ACI)
|
6
|
-
[![Coverage Status](https://coveralls.io/repos/ruby-rdf/rdf-n3/badge.svg)](https://coveralls.io/github/ruby-rdf/rdf-n3)
|
6
|
+
[![Coverage Status](https://coveralls.io/repos/github/ruby-rdf/rdf-n3/badge.svg?branch=develop)](https://coveralls.io/github/ruby-rdf/rdf-n3?branch=develop)
|
7
7
|
[![Gitter chat](https://badges.gitter.im/ruby-rdf/rdf.png)](https://gitter.im/ruby-rdf/rdf)
|
8
8
|
|
9
9
|
## Description
|
@@ -19,6 +19,7 @@ This version tracks the [W3C N3 Community Group][] [Specification][N3] which has
|
|
19
19
|
* The modifier `<-` is introduced as a synonym for `is ... of`.
|
20
20
|
* The SPARQL `BASE` and `PREFIX` declarations are supported.
|
21
21
|
* Implicit universal variables are defined at the top-level, rather than in the parent formula of the one in which they are defined.
|
22
|
+
* Support for explicit existential and universal variables (`@forAll` and `@forSome`) has been removed. Quick variables are the standard for universal quantification and blank nodes for existential, but scoping rules are different: Quickvars have top-level scope, and blank nodes formula scope.
|
22
23
|
|
23
24
|
This brings N3 closer to compatibility with Turtle.
|
24
25
|
|
@@ -27,6 +28,8 @@ RDF::N3 parses [Notation-3][N3], [Turtle][] and [N-Triples][] into statements or
|
|
27
28
|
|
28
29
|
Install with `gem install rdf-n3`
|
29
30
|
|
31
|
+
[Implementation Report](https://ruby-rdf.github.io/rdf-n3/etc/earl.html)
|
32
|
+
|
30
33
|
## Limitations
|
31
34
|
* Support for Variables in Formulae. Existential variables are quantified to RDF::Node instances, Universals to RDF::Query::Variable, with the URI of the variable target used as the variable name.
|
32
35
|
|
@@ -69,6 +72,7 @@ Reasoning is discussed in the [Design Issues][] document.
|
|
69
72
|
* `list:append` (See {RDF::N3::Algebra::List::Append})
|
70
73
|
* `list:first` (See {RDF::N3::Algebra::List::First})
|
71
74
|
* `list:in` (See {RDF::N3::Algebra::List::In})
|
75
|
+
* `list:iterate` (See {RDF::N3::Algebra::List::Iterate})
|
72
76
|
* `list:last` (See {RDF::N3::Algebra::List::Last})
|
73
77
|
* `list:length` (See {RDF::N3::Algebra::List::Length})
|
74
78
|
* `list:member` (See {RDF::N3::Algebra::List::Member})
|
@@ -78,9 +82,11 @@ Reasoning is discussed in the [Design Issues][] document.
|
|
78
82
|
* `log:conclusion` (See {RDF::N3::Algebra::Log::Conclusion})
|
79
83
|
* `log:conjunction` (See {RDF::N3::Algebra::Log::Conjunction})
|
80
84
|
* `log:content` (See {RDF::N3::Algebra::Log::Content})
|
85
|
+
* `log:dtlit` (See {RDF::N3::Algebra::Log::DtLit})
|
81
86
|
* `log:equalTo` (See {RDF::N3::Algebra::Log::EqualTo})
|
82
87
|
* `log:implies` (See {RDF::N3::Algebra::Log::Implies})
|
83
88
|
* `log:includes` (See {RDF::N3::Algebra::Log::Includes})
|
89
|
+
* `log:langlit` (See {RDF::N3::Algebra::Log::LangLit})
|
84
90
|
* `log:n3String` (See {RDF::N3::Algebra::Log::N3String})
|
85
91
|
* `log:notEqualTo` (See {RDF::N3::Algebra::Log::NotEqualTo})
|
86
92
|
* `log:notIncludes` (See {RDF::N3::Algebra::Log::NotIncludes})
|
@@ -139,7 +145,7 @@ Reasoning is discussed in the [Design Issues][] document.
|
|
139
145
|
* `string:scrape` (See {RDF::N3::Algebra::Str::Scrape})
|
140
146
|
* `string:startsWith` (See {RDF::N3::Algebra::Str::StartsWith})
|
141
147
|
|
142
|
-
#### RDF Time vocabulary
|
148
|
+
#### RDF Time vocabulary <http://www.w3.org/2000/10/swap/time#>
|
143
149
|
|
144
150
|
* `time:dayOfWeek` (See {RDF::N3::Algebra::Time::DayOfWeek})
|
145
151
|
* `time:day` (See {RDF::N3::Algebra::Time::Day})
|
@@ -173,15 +179,8 @@ when turned into an RDF Repository results in the following quads
|
|
173
179
|
Reasoning uses a Notation3 Algebra, similar to [SPARQL S-Expressions][]. This implementation considers formulae to be patterns, which may be asserted on statements made in the default graph, possibly loaded from a separate file. The logical relationships are reduced to algebraic operators.
|
174
180
|
|
175
181
|
### Variables
|
176
|
-
|
177
|
-
|
178
|
-
@forAll <#h>. @forSome <#g>. <#g> <#loves> <#h> .
|
179
|
-
|
180
|
-
results in:
|
181
|
-
|
182
|
-
h = RDF::Query::Variable.new(<#h>)
|
183
|
-
g = RDF::Node.new()
|
184
|
-
RDF::Statement(f, <#loves>, h)
|
182
|
+
The latest version of N3 supports only quickVars (e.g., `?x`). THe former explicit `@forAll` and `@forSome` of been removed.
|
183
|
+
Existential variables are replaced with an allocated `RDF::Node` instance.
|
185
184
|
|
186
185
|
Note that the behavior of both existential and universal variables is not entirely in keeping with the [Team Submission][], and neither work quite like SPARQL variables. When used in the antecedent part of an implication, universal variables should behave much like SPARQL variables. This area is subject to a fair amount of change.
|
187
186
|
|
@@ -194,11 +193,11 @@ Formulae are typically used to query the knowledge-base, which is set from the b
|
|
194
193
|
Blank nodes associated with rdf:List statements used as part of a built-in are made _non-distinguished_ existential variables, and patters containing these variables become optional. If they are not bound as part of the query, the implicitly are bound as the original blank nodes defined within the formula, which allows for both constant list arguments, list arguments that contain variables, or arguments which are variables expanding to lists.
|
195
194
|
|
196
195
|
## Dependencies
|
197
|
-
* [Ruby](https://ruby-lang.org/) (>= 2.
|
198
|
-
* [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.
|
199
|
-
* [EBNF][EBNF gem] (~> 2.
|
196
|
+
* [Ruby](https://ruby-lang.org/) (>= 2.6)
|
197
|
+
* [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.2)
|
198
|
+
* [EBNF][EBNF gem] (~> 2.2)
|
200
199
|
* [SPARQL][SPARQL gem] (~> 3.1)
|
201
|
-
* [SXP][SXP gem] (~> 1.
|
200
|
+
* [SXP][SXP gem] (~> 1.2)
|
202
201
|
|
203
202
|
## Documentation
|
204
203
|
Full documentation available on [RubyDoc.info](https://rubydoc.info/github/ruby-rdf/rdf-n3)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.2.0
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module RDF::N3::Algebra::List
|
2
|
+
##
|
3
|
+
# Generates a list of lists when each constituent list is composed of the index and value of each element in the subject.
|
4
|
+
#
|
5
|
+
# Binds variables in the object list.
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# { (1 2 3) list:iterate ((0 1) (1 2) (2 3)) } => { :test4a a :SUCCESS }.
|
9
|
+
class Iterate < RDF::N3::Algebra::ListOperator
|
10
|
+
NAME = :listIterate
|
11
|
+
URI = RDF::N3::List.iterate
|
12
|
+
|
13
|
+
##
|
14
|
+
# Evaluates this operator using the given variable `bindings`.
|
15
|
+
# The subject MUST evaluate to a list and the object to a list composed of two components: index and value.
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
# {(1 2 3) list:iterate (?x ?y)} => {:solution :is (?x ?y)} .
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
# {(1 2 3) list:iterate ?L} => {:solution :is ?L} .
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
# {(1 2 3) list:iterate (1 ?y)} => {:value :is ?y} .
|
25
|
+
#
|
26
|
+
# @example
|
27
|
+
# {(1 2 3) list:iterate (?x 2)} => {:index :is ?x} .
|
28
|
+
#
|
29
|
+
# @param [RDF::Queryable] queryable
|
30
|
+
# the graph or repository to query
|
31
|
+
# @param [RDF::Query::Solutions] solutions
|
32
|
+
# solutions for chained queries
|
33
|
+
# @return [RDF::Query::Solutions]
|
34
|
+
def execute(queryable, solutions:, **options)
|
35
|
+
RDF::Query::Solutions(solutions.map do |solution|
|
36
|
+
subject = operand(0).evaluate(solution.bindings, formulae: formulae) || operand(0)
|
37
|
+
# Might be a variable or node evaluating to a list in queryable, or might be a list with variables
|
38
|
+
# If subject evaluated to a BNode, re-expand as a list
|
39
|
+
subject = RDF::N3::List.try_list(subject, queryable).evaluate(solution.bindings, formulae: formulae)
|
40
|
+
next unless validate(subject)
|
41
|
+
|
42
|
+
object = operand(1).evaluate(solution.bindings, formulae: formulae) || operand(1)
|
43
|
+
next unless object
|
44
|
+
# If object evaluated to a BNode, re-expand as a list
|
45
|
+
object = RDF::N3::List.try_list(object, queryable).evaluate(solution.bindings, formulae: formulae) || object
|
46
|
+
|
47
|
+
if object.list? && object.variable?
|
48
|
+
# Create a solution for those entries in subject that match object
|
49
|
+
if object.length != 2
|
50
|
+
log_error(NAME) {"object is not a list with two entries: #{object.to_sxp}"}
|
51
|
+
next
|
52
|
+
end
|
53
|
+
if object.first.variable? && object.last.variable?
|
54
|
+
solutions = RDF::Query::Solutions.new
|
55
|
+
subject.each_with_index do |r, i|
|
56
|
+
s = solution.merge(object.first.to_sym => RDF::Literal(i), object.last.to_sym => r)
|
57
|
+
log_debug(self.class.const_get(:NAME), "result: #{s.to_sxp}")
|
58
|
+
solutions << s
|
59
|
+
end
|
60
|
+
solutions
|
61
|
+
elsif object.first.variable?
|
62
|
+
# Solution binds indexes to all matching values
|
63
|
+
solutions = RDF::Query::Solutions.new
|
64
|
+
subject.each_with_index do |r, i|
|
65
|
+
next unless r == object.last
|
66
|
+
s = solution.merge(object.first.to_sym => RDF::Literal(i))
|
67
|
+
log_debug(self.class.const_get(:NAME), "result: #{s.to_sxp}")
|
68
|
+
solutions << s
|
69
|
+
end
|
70
|
+
solutions
|
71
|
+
elsif object.last.variable?
|
72
|
+
# Solution binds value at specified index
|
73
|
+
next unless v = subject.at(object.first)
|
74
|
+
s = solution.merge(object.last.to_sym => v)
|
75
|
+
log_debug(self.class.const_get(:NAME), "result: #{s.to_sxp}")
|
76
|
+
s
|
77
|
+
end
|
78
|
+
elsif object.variable?
|
79
|
+
# Create a solution for each index/value pair in subject
|
80
|
+
solutions = RDF::Query::Solutions.new
|
81
|
+
subject.each_with_index do |r, i|
|
82
|
+
s = solution.merge(object.to_sym => RDF::N3::List[RDF::Literal(i), r])
|
83
|
+
log_debug(self.class.const_get(:NAME), "result: #{s.to_sxp}")
|
84
|
+
solutions << s
|
85
|
+
end
|
86
|
+
solutions
|
87
|
+
else
|
88
|
+
# Evaluates to true if the subject has a matching entry
|
89
|
+
same = subject.at(object.first) == object.last
|
90
|
+
log_debug(self.class.const_get(:NAME), "result: #{same.inspect}")
|
91
|
+
solution if same
|
92
|
+
end
|
93
|
+
end.flatten.compact.uniq)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -79,5 +79,18 @@ module RDF::N3::Algebra
|
|
79
79
|
false
|
80
80
|
end
|
81
81
|
end
|
82
|
+
|
83
|
+
##
|
84
|
+
# Returns a literal for the numeric argument.
|
85
|
+
def as_literal(object)
|
86
|
+
case object
|
87
|
+
when Float
|
88
|
+
literal = RDF::Literal(object, canonicalize: true)
|
89
|
+
literal.instance_variable_set(:@string, literal.to_s.downcase)
|
90
|
+
literal
|
91
|
+
else
|
92
|
+
RDF::Literal(object, canonicalize: true)
|
93
|
+
end
|
94
|
+
end
|
82
95
|
end
|
83
96
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module RDF::N3::Algebra::Log
|
2
|
+
##
|
3
|
+
# Takes a list of a string and an IRI and creates a datatyped literal.
|
4
|
+
class DtLit < RDF::N3::Algebra::ListOperator
|
5
|
+
NAME = :dtlit
|
6
|
+
URI = RDF::N3::Log.dtlit
|
7
|
+
|
8
|
+
##
|
9
|
+
# Reads the subject into the object.
|
10
|
+
#
|
11
|
+
# Returns nil if resource does not validate, given its position
|
12
|
+
#
|
13
|
+
# @param [RDF::N3::List] resource
|
14
|
+
# @return [RDF::Term]
|
15
|
+
def resolve(resource, position: :subject)
|
16
|
+
case position
|
17
|
+
when :subject
|
18
|
+
RDF::Literal(as_literal(resource.first).to_s, datatype: resource.last)
|
19
|
+
when :object
|
20
|
+
return nil unless resource.literal? || resource.variable?
|
21
|
+
resource
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def validate(list)
|
26
|
+
if super(list)
|
27
|
+
if list.length != 2
|
28
|
+
log_error(NAME) {"operand is not a list with two elements: #{list.to_sxp}"}
|
29
|
+
false
|
30
|
+
elsif !list.last.uri?
|
31
|
+
log_error(NAME) {"second component of subject must be an IRI: #{list.last.to_sxp}"}
|
32
|
+
false
|
33
|
+
else
|
34
|
+
true
|
35
|
+
end
|
36
|
+
else
|
37
|
+
false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module RDF::N3::Algebra::Log
|
2
|
+
##
|
3
|
+
# Takes a list of two strings creates a language-tagged literal.
|
4
|
+
class LangLit < RDF::N3::Algebra::ListOperator
|
5
|
+
NAME = :langlit
|
6
|
+
URI = RDF::N3::Log.langlit
|
7
|
+
|
8
|
+
##
|
9
|
+
# Reads the subject into the object.
|
10
|
+
#
|
11
|
+
# Returns nil if resource does not validate, given its position
|
12
|
+
#
|
13
|
+
# @param [RDF::N3::List] resource
|
14
|
+
# @return [RDF::Term]
|
15
|
+
def resolve(resource, position: :subject)
|
16
|
+
case position
|
17
|
+
when :subject
|
18
|
+
RDF::Literal(as_literal(resource.first).to_s, language: resource.last.to_s.to_sym)
|
19
|
+
when :object
|
20
|
+
return nil unless resource.literal? || resource.variable?
|
21
|
+
resource
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def validate(list)
|
26
|
+
if super(list)
|
27
|
+
if list.length != 2
|
28
|
+
log_error(NAME) {"operand is not a list with two elements: #{list.to_sxp}"}
|
29
|
+
false
|
30
|
+
elsif !list.last.to_s.match?(/^[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*$/)
|
31
|
+
log_warn(NAME) {"second component of subject should be BCP47 language tag: #{list.last.to_sxp}"}
|
32
|
+
false
|
33
|
+
else
|
34
|
+
true
|
35
|
+
end
|
36
|
+
else
|
37
|
+
false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -49,7 +49,6 @@ module RDF::N3::Algebra
|
|
49
49
|
res = apply(lhs, rhs)
|
50
50
|
log_debug(self.class.const_get(:NAME), "result") {SXP::Generator.string(res.to_sxp_bin).strip}
|
51
51
|
# Return the result applying subject and object
|
52
|
-
#require 'byebug'; byebug
|
53
52
|
case res
|
54
53
|
when RDF::Literal::TRUE
|
55
54
|
solution
|
data/lib/rdf/n3/algebra.rb
CHANGED
@@ -19,6 +19,7 @@ module RDF::N3
|
|
19
19
|
autoload :Append, 'rdf/n3/algebra/list/append'
|
20
20
|
autoload :First, 'rdf/n3/algebra/list/first'
|
21
21
|
autoload :In, 'rdf/n3/algebra/list/in'
|
22
|
+
autoload :Iterate, 'rdf/n3/algebra/list/iterate'
|
22
23
|
autoload :Last, 'rdf/n3/algebra/list/last'
|
23
24
|
autoload :Length, 'rdf/n3/algebra/list/length'
|
24
25
|
autoload :Member, 'rdf/n3/algebra/list/member'
|
@@ -30,9 +31,11 @@ module RDF::N3
|
|
30
31
|
autoload :Conclusion, 'rdf/n3/algebra/log/conclusion'
|
31
32
|
autoload :Conjunction, 'rdf/n3/algebra/log/conjunction'
|
32
33
|
autoload :Content, 'rdf/n3/algebra/log/content'
|
34
|
+
autoload :DtLit, 'rdf/n3/algebra/log/dtlit'
|
33
35
|
autoload :EqualTo, 'rdf/n3/algebra/log/equal_to'
|
34
36
|
autoload :Implies, 'rdf/n3/algebra/log/implies'
|
35
37
|
autoload :Includes, 'rdf/n3/algebra/log/includes'
|
38
|
+
autoload :LangLit, 'rdf/n3/algebra/log/langlit'
|
36
39
|
autoload :N3String, 'rdf/n3/algebra/log/n3_string'
|
37
40
|
autoload :NotEqualTo, 'rdf/n3/algebra/log/not_equal_to'
|
38
41
|
autoload :NotIncludes, 'rdf/n3/algebra/log/not_includes'
|
@@ -117,6 +120,7 @@ module RDF::N3
|
|
117
120
|
RDF::N3::List.append => List.const_get(:Append),
|
118
121
|
RDF::N3::List.first => List.const_get(:First),
|
119
122
|
RDF::N3::List.in => List.const_get(:In),
|
123
|
+
RDF::N3::List.iterate => List.const_get(:Iterate),
|
120
124
|
RDF::N3::List.last => List.const_get(:Last),
|
121
125
|
RDF::N3::List.length => List.const_get(:Length),
|
122
126
|
RDF::N3::List.member => List.const_get(:Member),
|
@@ -124,9 +128,11 @@ module RDF::N3
|
|
124
128
|
RDF::N3::Log.conclusion => Log.const_get(:Conclusion),
|
125
129
|
RDF::N3::Log.conjunction => Log.const_get(:Conjunction),
|
126
130
|
RDF::N3::Log.content => Log.const_get(:Content),
|
131
|
+
RDF::N3::Log.dtlit => Log.const_get(:DtLit),
|
127
132
|
RDF::N3::Log.equalTo => Log.const_get(:EqualTo),
|
128
133
|
RDF::N3::Log.implies => Log.const_get(:Implies),
|
129
134
|
RDF::N3::Log.includes => Log.const_get(:Includes),
|
135
|
+
RDF::N3::Log.langlit => Log.const_get(:LangLit),
|
130
136
|
RDF::N3::Log.n3String => Log.const_get(:N3String),
|
131
137
|
RDF::N3::Log.notEqualTo => Log.const_get(:NotEqualTo),
|
132
138
|
RDF::N3::Log.notIncludes => Log.const_get(:NotIncludes),
|
data/lib/rdf/n3/extensions.rb
CHANGED
data/lib/rdf/n3/reader.rb
CHANGED
@@ -12,7 +12,7 @@ module RDF::N3
|
|
12
12
|
#
|
13
13
|
# Separate pass to create branch_table from n3-selectors.n3
|
14
14
|
#
|
15
|
-
# This implementation
|
15
|
+
# This implementation only supports quickVars at the document scope.
|
16
16
|
#
|
17
17
|
# Non-distinguished blank node variables are created as part of reasoning.
|
18
18
|
#
|
@@ -200,7 +200,6 @@ module RDF::N3
|
|
200
200
|
|<-|<=|=>|=
|
201
201
|
| true|false
|
202
202
|
| has|is|of
|
203
|
-
|@forAll|@forSome
|
204
203
|
)x)
|
205
204
|
|
206
205
|
terminal(:PREFIX, PREFIX)
|
@@ -244,7 +243,6 @@ module RDF::N3
|
|
244
243
|
def read_n3Statement
|
245
244
|
prod(:n3Statement, %w{.}) do
|
246
245
|
error("read_n3Doc", "Unexpected end of file") unless token = @lexer.first
|
247
|
-
read_uniext ||
|
248
246
|
read_triples ||
|
249
247
|
error("Expected token", production: :statement, token: token)
|
250
248
|
end
|
@@ -573,12 +571,6 @@ module RDF::N3
|
|
573
571
|
formula_nodes[node] = true
|
574
572
|
debug(:formula, depth: @options[:depth]) {"id: #{node}, depth: #{formulae.length}"}
|
575
573
|
|
576
|
-
# Promote variables defined on the earlier formula to this formula
|
577
|
-
variables[node] = {}
|
578
|
-
variables.fetch(formulae[-2], {}).each do |name, var|
|
579
|
-
variables[node][name] = var
|
580
|
-
end
|
581
|
-
|
582
574
|
read_formulaContent
|
583
575
|
|
584
576
|
# Pop off the formula
|
@@ -664,54 +656,7 @@ module RDF::N3
|
|
664
656
|
prod(:quickVar) do
|
665
657
|
token = @lexer.shift
|
666
658
|
value = token.value.sub('?', '')
|
667
|
-
|
668
|
-
variables[nil][iri] ||= univar(iri, scope: nil)
|
669
|
-
end
|
670
|
-
end
|
671
|
-
end
|
672
|
-
|
673
|
-
##
|
674
|
-
# Read a list of IRIs
|
675
|
-
#
|
676
|
-
# [27] iriList ::= iri ( ',' iri )*
|
677
|
-
#
|
678
|
-
# @return [Array<RDF::URI>] the list of IRIs
|
679
|
-
def read_irilist
|
680
|
-
iris = []
|
681
|
-
prod(:iriList, %{,}) do
|
682
|
-
while iri = read_iri
|
683
|
-
iris << iri
|
684
|
-
break unless @lexer.first === ','
|
685
|
-
@lexer.shift while @lexer.first === ','
|
686
|
-
end
|
687
|
-
end
|
688
|
-
iris
|
689
|
-
end
|
690
|
-
|
691
|
-
##
|
692
|
-
# Read a univeral or existential
|
693
|
-
#
|
694
|
-
# Apart from the set of statements, a formula also has a set of URIs of symbols which are universally quantified,
|
695
|
-
# and a set of URIs of symbols which are existentially quantified.
|
696
|
-
# Variables are then in general symbols which have been quantified.
|
697
|
-
#
|
698
|
-
# Here we allocate a variable (making up a name) and record with the defining formula. Quantification is done
|
699
|
-
# when the formula is completed against all in-scope variables
|
700
|
-
#
|
701
|
-
# [31] existential ::= '@forSome' iriList
|
702
|
-
# [32] universal ::= '@forAll' iriList
|
703
|
-
#
|
704
|
-
# @return [void]
|
705
|
-
def read_uniext
|
706
|
-
if %w(@forSome @forAll).include?(@lexer.first.value)
|
707
|
-
token = @lexer.shift
|
708
|
-
prod(token === '@forAll' ? :universal : :existential) do
|
709
|
-
iri_list = read_irilist
|
710
|
-
iri_list.each do |iri|
|
711
|
-
# Note, this might re-create an equivalent variable already defined in this formula, and replaces an equivalent variable that may have been defined in the parent formula.
|
712
|
-
var = univar(iri, scope: formulae.last, existential: token === '@forSome')
|
713
|
-
add_var_to_formula(formulae.last, iri, var)
|
714
|
-
end
|
659
|
+
variables[value] ||= RDF::Query::Variable.new(value)
|
715
660
|
end
|
716
661
|
end
|
717
662
|
end
|
@@ -786,10 +731,9 @@ module RDF::N3
|
|
786
731
|
end
|
787
732
|
|
788
733
|
# If not in ground formula, note scope, and if existential
|
789
|
-
def univar(label, scope
|
790
|
-
value =
|
791
|
-
value
|
792
|
-
RDF::Query::Variable.new(value, existential: existential)
|
734
|
+
def univar(label, scope:)
|
735
|
+
value = label
|
736
|
+
RDF::Query::Variable.new(value)
|
793
737
|
end
|
794
738
|
|
795
739
|
# add a pattern or statement
|
@@ -865,20 +809,11 @@ module RDF::N3
|
|
865
809
|
label
|
866
810
|
end
|
867
811
|
|
868
|
-
# Find any variable that may be defined
|
812
|
+
# Find any variable that may be defined identified by `name`
|
869
813
|
# @param [RDF::Node] name of formula
|
870
814
|
# @return [RDF::Query::Variable]
|
871
815
|
def find_var(name)
|
872
|
-
|
873
|
-
end
|
874
|
-
|
875
|
-
# Add a variable to the formula identified by `bn`, returning the variable. Useful as an LRU for variable name lookups
|
876
|
-
# @param [RDF::Node] bn name of formula
|
877
|
-
# @param [#to_s] name of variable for lookup
|
878
|
-
# @param [RDF::Query::Variable] var
|
879
|
-
# @return [RDF::Query::Variable]
|
880
|
-
def add_var_to_formula(bn, name, var)
|
881
|
-
(variables[bn] ||= {})[name.to_s] = var
|
816
|
+
variables[name.to_s]
|
882
817
|
end
|
883
818
|
|
884
819
|
def prod(production, recover_to = [])
|
data/lib/rdf/n3/terminals.rb
CHANGED
data/lib/rdf/n3/writer.rb
CHANGED
@@ -273,13 +273,26 @@ module RDF::N3
|
|
273
273
|
case literal
|
274
274
|
when RDF::Literal
|
275
275
|
case literal.valid? ? literal.datatype : false
|
276
|
-
when RDF::XSD.boolean
|
277
|
-
literal.canonicalize.to_s
|
276
|
+
when RDF::XSD.boolean
|
277
|
+
%w(true false).include?(literal.value) ? literal.value : literal.canonicalize.to_s
|
278
|
+
when RDF::XSD.integer
|
279
|
+
literal.value.match?(/^[\+\-]?\d+$/) && !canonicalize? ? literal.value : literal.canonicalize.to_s
|
280
|
+
when RDF::XSD.decimal
|
281
|
+
literal.value.match?(/^[\+\-]?\d+\.\d+?$/) && !canonicalize? ?
|
282
|
+
literal.value :
|
283
|
+
literal.canonicalize.to_s
|
278
284
|
when RDF::XSD.double
|
279
285
|
if literal.nan? || literal.infinite?
|
280
286
|
quoted(literal.value) + "^^#{format_uri(literal.datatype)}"
|
281
287
|
else
|
282
|
-
literal.
|
288
|
+
in_form = case literal.value
|
289
|
+
when /[\+\-]?\d+\.\d*E[\+\-]?\d+$/i then true
|
290
|
+
when /[\+\-]?\.\d+E[\+\-]?\d+$/i then true
|
291
|
+
when /[\+\-]?\d+E[\+\-]?\d+$/i then true
|
292
|
+
else false
|
293
|
+
end && !canonicalize?
|
294
|
+
|
295
|
+
in_form ? literal.value : literal.canonicalize.to_s.sub('E', 'e')
|
283
296
|
end
|
284
297
|
else
|
285
298
|
text = quoted(literal.value)
|
@@ -331,19 +344,6 @@ module RDF::N3
|
|
331
344
|
prefixes.keys.sort_by(&:to_s).each do |prefix|
|
332
345
|
@output.write("@prefix #{prefix}: <#{prefixes[prefix]}> .\n")
|
333
346
|
end
|
334
|
-
|
335
|
-
# Universals and extentials at top-level
|
336
|
-
unless @universals.empty?
|
337
|
-
log_debug("start_document: universals") { @universals.inspect}
|
338
|
-
terms = @universals.map {|v| format_uri(RDF::URI(v.name.to_s))}
|
339
|
-
@output.write("@forAll #{terms.join(', ')} .\n")
|
340
|
-
end
|
341
|
-
|
342
|
-
unless @existentials.empty?
|
343
|
-
log_debug("start_document: existentials") { @existentials.inspect}
|
344
|
-
terms = @existentials.map {|v| format_uri(RDF::URI(v.name.to_s.sub(/_ext$/, '')))}
|
345
|
-
@output.write("@forSome #{terms.join(', ')} .\n")
|
346
|
-
end
|
347
347
|
end
|
348
348
|
|
349
349
|
# Defines rdf:type of subjects to be emitted at the beginning of the graph. Defaults to rdfs:Class
|
@@ -424,10 +424,6 @@ module RDF::N3
|
|
424
424
|
|
425
425
|
@options[:prefixes] = {} # Will define actual used when matched
|
426
426
|
repo.each {|statement| preprocess_statement(statement)}
|
427
|
-
|
428
|
-
vars = repo.enum_term.to_a.uniq.select {|r| r.is_a?(RDF::Query::Variable) && !r.to_s.end_with?('_quick')}
|
429
|
-
@universals = vars.reject(&:existential?)
|
430
|
-
@existentials = vars - @universals
|
431
427
|
end
|
432
428
|
|
433
429
|
# Perform any statement preprocessing required. This is used to perform reference counts and determine required
|
@@ -462,7 +458,6 @@ module RDF::N3
|
|
462
458
|
|
463
459
|
# Reset internal helper instance variables
|
464
460
|
def reset
|
465
|
-
@universals, @existentials = [], []
|
466
461
|
@lists = {}
|
467
462
|
@references = {}
|
468
463
|
@serialized = {}
|
@@ -521,11 +516,7 @@ module RDF::N3
|
|
521
516
|
def p_term(resource, position)
|
522
517
|
#log_debug("p_term") {"#{resource.to_sxp}, #{position}"}
|
523
518
|
l = if resource.is_a?(RDF::Query::Variable)
|
524
|
-
|
525
|
-
'?' + RDF::URI(resource.name).fragment.sub(/_quick$/, '')
|
526
|
-
else
|
527
|
-
format_term(RDF::URI(resource.name.to_s.sub(/_ext$/, '')))
|
528
|
-
end
|
519
|
+
"?#{resource.name}"
|
529
520
|
elsif resource == RDF.nil
|
530
521
|
"()"
|
531
522
|
else
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rdf-n3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gregg
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-12-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ebnf
|
@@ -17,138 +17,126 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: '2.
|
20
|
+
version: '2.2'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: '2.
|
27
|
+
version: '2.2'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: rdf
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
32
|
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: '3.
|
35
|
-
- - ">="
|
36
|
-
- !ruby/object:Gem::Version
|
37
|
-
version: 3.1.8
|
34
|
+
version: '3.2'
|
38
35
|
type: :runtime
|
39
36
|
prerelease: false
|
40
37
|
version_requirements: !ruby/object:Gem::Requirement
|
41
38
|
requirements:
|
42
39
|
- - "~>"
|
43
40
|
- !ruby/object:Gem::Version
|
44
|
-
version: '3.
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 3.1.8
|
41
|
+
version: '3.2'
|
48
42
|
- !ruby/object:Gem::Dependency
|
49
43
|
name: sparql
|
50
44
|
requirement: !ruby/object:Gem::Requirement
|
51
45
|
requirements:
|
52
46
|
- - "~>"
|
53
47
|
- !ruby/object:Gem::Version
|
54
|
-
version: '3.
|
55
|
-
- - ">="
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
version: 3.1.4
|
48
|
+
version: '3.2'
|
58
49
|
type: :runtime
|
59
50
|
prerelease: false
|
60
51
|
version_requirements: !ruby/object:Gem::Requirement
|
61
52
|
requirements:
|
62
53
|
- - "~>"
|
63
54
|
- !ruby/object:Gem::Version
|
64
|
-
version: '3.
|
65
|
-
- - ">="
|
66
|
-
- !ruby/object:Gem::Version
|
67
|
-
version: 3.1.4
|
55
|
+
version: '3.2'
|
68
56
|
- !ruby/object:Gem::Dependency
|
69
57
|
name: sxp
|
70
58
|
requirement: !ruby/object:Gem::Requirement
|
71
59
|
requirements:
|
72
60
|
- - "~>"
|
73
61
|
- !ruby/object:Gem::Version
|
74
|
-
version: '1.
|
62
|
+
version: '1.2'
|
75
63
|
type: :runtime
|
76
64
|
prerelease: false
|
77
65
|
version_requirements: !ruby/object:Gem::Requirement
|
78
66
|
requirements:
|
79
67
|
- - "~>"
|
80
68
|
- !ruby/object:Gem::Version
|
81
|
-
version: '1.
|
69
|
+
version: '1.2'
|
82
70
|
- !ruby/object:Gem::Dependency
|
83
71
|
name: json-ld
|
84
72
|
requirement: !ruby/object:Gem::Requirement
|
85
73
|
requirements:
|
86
74
|
- - "~>"
|
87
75
|
- !ruby/object:Gem::Version
|
88
|
-
version: '3.
|
76
|
+
version: '3.2'
|
89
77
|
type: :development
|
90
78
|
prerelease: false
|
91
79
|
version_requirements: !ruby/object:Gem::Requirement
|
92
80
|
requirements:
|
93
81
|
- - "~>"
|
94
82
|
- !ruby/object:Gem::Version
|
95
|
-
version: '3.
|
83
|
+
version: '3.2'
|
96
84
|
- !ruby/object:Gem::Dependency
|
97
85
|
name: rdf-spec
|
98
86
|
requirement: !ruby/object:Gem::Requirement
|
99
87
|
requirements:
|
100
88
|
- - "~>"
|
101
89
|
- !ruby/object:Gem::Version
|
102
|
-
version: '3.
|
90
|
+
version: '3.2'
|
103
91
|
type: :development
|
104
92
|
prerelease: false
|
105
93
|
version_requirements: !ruby/object:Gem::Requirement
|
106
94
|
requirements:
|
107
95
|
- - "~>"
|
108
96
|
- !ruby/object:Gem::Version
|
109
|
-
version: '3.
|
97
|
+
version: '3.2'
|
110
98
|
- !ruby/object:Gem::Dependency
|
111
99
|
name: rdf-isomorphic
|
112
100
|
requirement: !ruby/object:Gem::Requirement
|
113
101
|
requirements:
|
114
102
|
- - "~>"
|
115
103
|
- !ruby/object:Gem::Version
|
116
|
-
version: '3.
|
104
|
+
version: '3.2'
|
117
105
|
type: :development
|
118
106
|
prerelease: false
|
119
107
|
version_requirements: !ruby/object:Gem::Requirement
|
120
108
|
requirements:
|
121
109
|
- - "~>"
|
122
110
|
- !ruby/object:Gem::Version
|
123
|
-
version: '3.
|
111
|
+
version: '3.2'
|
124
112
|
- !ruby/object:Gem::Dependency
|
125
113
|
name: rdf-trig
|
126
114
|
requirement: !ruby/object:Gem::Requirement
|
127
115
|
requirements:
|
128
116
|
- - "~>"
|
129
117
|
- !ruby/object:Gem::Version
|
130
|
-
version: '3.
|
118
|
+
version: '3.2'
|
131
119
|
type: :development
|
132
120
|
prerelease: false
|
133
121
|
version_requirements: !ruby/object:Gem::Requirement
|
134
122
|
requirements:
|
135
123
|
- - "~>"
|
136
124
|
- !ruby/object:Gem::Version
|
137
|
-
version: '3.
|
125
|
+
version: '3.2'
|
138
126
|
- !ruby/object:Gem::Dependency
|
139
127
|
name: rdf-vocab
|
140
128
|
requirement: !ruby/object:Gem::Requirement
|
141
129
|
requirements:
|
142
130
|
- - "~>"
|
143
131
|
- !ruby/object:Gem::Version
|
144
|
-
version: '3.
|
132
|
+
version: '3.2'
|
145
133
|
type: :development
|
146
134
|
prerelease: false
|
147
135
|
version_requirements: !ruby/object:Gem::Requirement
|
148
136
|
requirements:
|
149
137
|
- - "~>"
|
150
138
|
- !ruby/object:Gem::Version
|
151
|
-
version: '3.
|
139
|
+
version: '3.2'
|
152
140
|
- !ruby/object:Gem::Dependency
|
153
141
|
name: rspec
|
154
142
|
requirement: !ruby/object:Gem::Requirement
|
@@ -208,6 +196,7 @@ files:
|
|
208
196
|
- lib/rdf/n3/algebra/list/append.rb
|
209
197
|
- lib/rdf/n3/algebra/list/first.rb
|
210
198
|
- lib/rdf/n3/algebra/list/in.rb
|
199
|
+
- lib/rdf/n3/algebra/list/iterate.rb
|
211
200
|
- lib/rdf/n3/algebra/list/last.rb
|
212
201
|
- lib/rdf/n3/algebra/list/length.rb
|
213
202
|
- lib/rdf/n3/algebra/list/member.rb
|
@@ -215,9 +204,11 @@ files:
|
|
215
204
|
- lib/rdf/n3/algebra/log/conclusion.rb
|
216
205
|
- lib/rdf/n3/algebra/log/conjunction.rb
|
217
206
|
- lib/rdf/n3/algebra/log/content.rb
|
207
|
+
- lib/rdf/n3/algebra/log/dtlit.rb
|
218
208
|
- lib/rdf/n3/algebra/log/equal_to.rb
|
219
209
|
- lib/rdf/n3/algebra/log/implies.rb
|
220
210
|
- lib/rdf/n3/algebra/log/includes.rb
|
211
|
+
- lib/rdf/n3/algebra/log/langlit.rb
|
221
212
|
- lib/rdf/n3/algebra/log/n3_string.rb
|
222
213
|
- lib/rdf/n3/algebra/log/not_equal_to.rb
|
223
214
|
- lib/rdf/n3/algebra/log/not_includes.rb
|
@@ -305,14 +296,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
305
296
|
requirements:
|
306
297
|
- - ">="
|
307
298
|
- !ruby/object:Gem::Version
|
308
|
-
version: '2.
|
299
|
+
version: '2.6'
|
309
300
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
310
301
|
requirements:
|
311
302
|
- - ">="
|
312
303
|
- !ruby/object:Gem::Version
|
313
304
|
version: '0'
|
314
305
|
requirements: []
|
315
|
-
rubygems_version: 3.
|
306
|
+
rubygems_version: 3.3.3
|
316
307
|
signing_key:
|
317
308
|
specification_version: 4
|
318
309
|
summary: Notation3 reader/writer and reasoner for RDF.rb.
|