sparql 1.0.6 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. data/README.md +11 -4
  2. data/VERSION +1 -1
  3. data/lib/sparql/algebra/extensions.rb +36 -0
  4. data/lib/sparql/algebra/operator.rb +197 -87
  5. data/lib/sparql/algebra/operator/abs.rb +31 -0
  6. data/lib/sparql/algebra/operator/base.rb +1 -0
  7. data/lib/sparql/algebra/operator/bnode.rb +88 -0
  8. data/lib/sparql/algebra/operator/bound.rb +2 -1
  9. data/lib/sparql/algebra/operator/ceil.rb +31 -0
  10. data/lib/sparql/algebra/operator/coalesce.rb +65 -0
  11. data/lib/sparql/algebra/operator/concat.rb +49 -0
  12. data/lib/sparql/algebra/operator/contains.rb +44 -0
  13. data/lib/sparql/algebra/operator/dataset.rb +11 -48
  14. data/lib/sparql/algebra/operator/datatype.rb +4 -2
  15. data/lib/sparql/algebra/operator/day.rb +31 -0
  16. data/lib/sparql/algebra/operator/encode_for_uri.rb +38 -0
  17. data/lib/sparql/algebra/operator/extend.rb +31 -2
  18. data/lib/sparql/algebra/operator/floor.rb +33 -0
  19. data/lib/sparql/algebra/operator/hours.rb +31 -0
  20. data/lib/sparql/algebra/operator/if.rb +55 -0
  21. data/lib/sparql/algebra/operator/in.rb +68 -0
  22. data/lib/sparql/algebra/operator/iri.rb +40 -0
  23. data/lib/sparql/algebra/operator/is_numeric.rb +41 -0
  24. data/lib/sparql/algebra/operator/lang_matches.rb +2 -2
  25. data/lib/sparql/algebra/operator/lcase.rb +31 -0
  26. data/lib/sparql/algebra/operator/md5.rb +34 -0
  27. data/lib/sparql/algebra/operator/minutes.rb +31 -0
  28. data/lib/sparql/algebra/operator/month.rb +31 -0
  29. data/lib/sparql/algebra/operator/not.rb +2 -2
  30. data/lib/sparql/algebra/operator/notin.rb +70 -0
  31. data/lib/sparql/algebra/operator/now.rb +29 -0
  32. data/lib/sparql/algebra/operator/order.rb +9 -13
  33. data/lib/sparql/algebra/operator/rand.rb +24 -0
  34. data/lib/sparql/algebra/operator/replace.rb +81 -0
  35. data/lib/sparql/algebra/operator/round.rb +31 -0
  36. data/lib/sparql/algebra/operator/seconds.rb +31 -0
  37. data/lib/sparql/algebra/operator/sha1.rb +34 -0
  38. data/lib/sparql/algebra/operator/sha256.rb +34 -0
  39. data/lib/sparql/algebra/operator/sha384.rb +34 -0
  40. data/lib/sparql/algebra/operator/sha512.rb +34 -0
  41. data/lib/sparql/algebra/operator/strafter.rb +57 -0
  42. data/lib/sparql/algebra/operator/strbefore.rb +59 -0
  43. data/lib/sparql/algebra/operator/strdt.rb +33 -0
  44. data/lib/sparql/algebra/operator/strends.rb +46 -0
  45. data/lib/sparql/algebra/operator/strlang.rb +34 -0
  46. data/lib/sparql/algebra/operator/strlen.rb +34 -0
  47. data/lib/sparql/algebra/operator/strstarts.rb +46 -0
  48. data/lib/sparql/algebra/operator/struuid.rb +32 -0
  49. data/lib/sparql/algebra/operator/substr.rb +80 -0
  50. data/lib/sparql/algebra/operator/timezone.rb +34 -0
  51. data/lib/sparql/algebra/operator/tz.rb +31 -0
  52. data/lib/sparql/algebra/operator/ucase.rb +31 -0
  53. data/lib/sparql/algebra/operator/uuid.rb +32 -0
  54. data/lib/sparql/algebra/operator/year.rb +31 -0
  55. data/lib/sparql/grammar/parser11.rb +128 -70
  56. data/lib/sparql/grammar/terminals11.rb +4 -5
  57. metadata +62 -7
data/README.md CHANGED
@@ -10,6 +10,7 @@ This is a [Ruby][] implementation of [SPARQL][] for [RDF.rb][].
10
10
 
11
11
  * 100% free and unencumbered [public domain](http://unlicense.org/) software.
12
12
  * [SPARQL 1.0][] query parsing and execution
13
+ * Limited [SPARQL 1.1][] query parsing and execution
13
14
  * SPARQL results as [XML][SPARQL XML], [JSON][SPARQL JSON] or HTML.
14
15
  * SPARQL CONSTRUCT or DESCRIBE serialized based on Format, Extension of Mime Type
15
16
  using available RDF Writers (see [Linked Data][])
@@ -45,9 +46,10 @@ much more capability than [SPARQL 1.0][], but has a few limitations:
45
46
  used in the object position, where the statement or pattern is terminated by a "."
46
47
  must contain whitespace separating the BNode label, and the ".".
47
48
 
48
- With this release, no new functionality is added beyond [SPARQL 1.0][]. Future releases
49
- will add more capabilities from [SPARQL 1.1][] with the ultimate objective of being
50
- completely [SPARQL 1.1][] Query and Update compliant.
49
+ The SPARQL gem now implements the following [SPARQL 1.1][] operations:
50
+
51
+ * Support for all [functions](http://www.w3.org/TR/sparql11-query/#SparqlOps).
52
+ * Support for [BIND](http://www.w3.org/TR/sparql11-query/#bind)
51
53
 
52
54
  ### Middleware
53
55
 
@@ -190,7 +192,7 @@ Full documentation available on [Rubydoc.info][SPARQL doc]
190
192
  ## Dependencies
191
193
 
192
194
  * [Ruby](http://ruby-lang.org/) (>= 1.9.2)
193
- * [RDF.rb](http://rubygems.org/gems/rdf) (>= 1.0)
195
+ * [RDF.rb](http://rubygems.org/gems/rdf) (>= 1.1)
194
196
  * [SPARQL::Client](https://rubygems.org/gems/sparql-client) (>= 1.0)
195
197
  * [SXP](https://rubygems.org/gems/sxp) (>= 0.1.0)
196
198
  * [Builder](https://rubygems.org/gems/builder) (>= 3.0.0)
@@ -245,6 +247,8 @@ To get a local working copy of the development repository, do:
245
247
  This is free and unencumbered public domain software. For more information,
246
248
  see <http://unlicense.org/> or the accompanying {file:UNLICENSE} file.
247
249
 
250
+ A copy of the [SPARQL 1.0 tests][] and [SPARQL 1.1 tests][] are included in the repository, which are not covered under the UNLICENSE; see the references for test copyright information.
251
+
248
252
  [Ruby]: http://ruby-lang.org/
249
253
  [RDF]: http://www.w3.org/RDF/
250
254
  [RDF::DO]: http://rubygems.org/gems/rdf-do
@@ -255,6 +259,8 @@ see <http://unlicense.org/> or the accompanying {file:UNLICENSE} file.
255
259
  [PDD]: http://lists.w3.org/Archives/Public/public-rdf-ruby/2010May/0013.html
256
260
  [SPARQL]: http://en.wikipedia.org/wiki/SPARQL
257
261
  [SPARQL 1.0]: http://www.w3.org/TR/rdf-sparql-query/
262
+ [SPARQL 1.0 tests]:http://www.w3.org/2001/sw/DataAccess/tests/
263
+ [SPARQL 1.1 tests]: http://www.w3.org/2009/sparql/docs/tests/
258
264
  [SPARQL 1.1]: http://www.w3.org/TR/sparql11-query/
259
265
  [SSE]: http://openjena.org/wiki/SSE
260
266
  [SXP]: http://sxp.rubyforge.org/
@@ -271,3 +277,4 @@ see <http://unlicense.org/> or the accompanying {file:UNLICENSE} file.
271
277
  [Rack]: http://rack.rubyforge.org/
272
278
  [Sinatra]: http://www.sinatrarb.com/
273
279
  [conneg]: http://en.wikipedia.org/wiki/Content_negotiation
280
+
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.6
1
+ 1.0.7
@@ -54,6 +54,40 @@ module RDF::Term
54
54
  def evaluate(bindings)
55
55
  self
56
56
  end
57
+
58
+ # Term compatibility according to SPARQL
59
+ #
60
+ # Compatibility of two arguments is defined as:
61
+ # * The arguments are simple literals or literals typed as xsd:string
62
+ # * The arguments are plain literals with identical language tags
63
+ # * The first argument is a plain literal with language tag and the second argument is a simple literal or literal typed as xsd:string
64
+ #
65
+ # @example
66
+ # compatible?("abc" "b") #=> true
67
+ # compatible?("abc" "b"^^xsd:string) #=> true
68
+ # compatible?("abc"^^xsd:string "b") #=> true
69
+ # compatible?("abc"^^xsd:string "b"^^xsd:string) #=> true
70
+ # compatible?("abc"@en "b") #=> true
71
+ # compatible?("abc"@en "b"^^xsd:string) #=> true
72
+ # compatible?("abc"@en "b"@en) #=> true
73
+ # compatible?("abc"@fr "b"@ja) #=> false
74
+ # compatible?("abc" "b"@ja) #=> false
75
+ # compatible?("abc" "b"@en) #=> false
76
+ # compatible?("abc"^^xsd:string "b"@en) #=> false
77
+ #
78
+ # @see http://www.w3.org/TR/sparql11-query/#func-arg-compatibility
79
+ def compatible?(other)
80
+ return false unless literal? && other.literal? && plain? && other.plain?
81
+
82
+ dtr = RDF::VERSION.to_s >= "1.1" ? other.datatype : (other.has_language? ? RDF.langString : RDF::XSD.string)
83
+
84
+ # * The arguments are simple literals or literals typed as xsd:string
85
+ # * The arguments are plain literals with identical language tags
86
+ # * The first argument is a plain literal with language tag and the second argument is a simple literal or literal typed as xsd:string
87
+ has_language? ?
88
+ (language == other.language || dtr == RDF::XSD.string) :
89
+ dtr == RDF::XSD.string
90
+ end
57
91
  end # RDF::Term
58
92
 
59
93
  # Override RDF::Queryable to execute against SPARQL::Algebra::Query elements as well as RDF::Query and RDF::Pattern
@@ -139,7 +173,9 @@ class RDF::Query::Variable
139
173
  #
140
174
  # @param [RDF::Query::Solution, #[]] bindings
141
175
  # @return [RDF::Term] the value of this variable
176
+ # @raise [TypeError] if the variable is not bound
142
177
  def evaluate(bindings = {})
178
+ raise TypeError if bindings.respond_to?(:bound?) && !bindings.bound?(self)
143
179
  bindings[name.to_sym]
144
180
  end
145
181
  end # RDF::Query::Variable
@@ -6,42 +6,84 @@ module SPARQL; module Algebra
6
6
  class Operator
7
7
  include Expression
8
8
 
9
+ # Nullary operatos
10
+ autoload :Now, 'sparql/algebra/operator/now'
11
+ autoload :Rand, 'sparql/algebra/operator/rand'
12
+ autoload :StrUUID, 'sparql/algebra/operator/struuid'
13
+ autoload :UUID, 'sparql/algebra/operator/uuid'
14
+
9
15
  # Unary operators
10
- autoload :Not, 'sparql/algebra/operator/not'
11
- autoload :Plus, 'sparql/algebra/operator/plus'
12
- autoload :Minus, 'sparql/algebra/operator/minus'
16
+ autoload :Abs, 'sparql/algebra/operator/abs'
17
+ autoload :BNode, 'sparql/algebra/operator/bnode'
13
18
  autoload :Bound, 'sparql/algebra/operator/bound'
19
+ autoload :Ceil, 'sparql/algebra/operator/ceil'
20
+ autoload :Datatype, 'sparql/algebra/operator/datatype'
21
+ autoload :Day, 'sparql/algebra/operator/day'
22
+ autoload :EncodeForURI, 'sparql/algebra/operator/encode_for_uri'
23
+ autoload :Floor, 'sparql/algebra/operator/floor'
24
+ autoload :Hours, 'sparql/algebra/operator/hours'
14
25
  autoload :IsBlank, 'sparql/algebra/operator/is_blank'
15
26
  autoload :IsIRI, 'sparql/algebra/operator/is_iri'
16
- autoload :IsURI, 'sparql/algebra/operator/is_iri'
17
27
  autoload :IsLiteral, 'sparql/algebra/operator/is_literal'
18
- autoload :Str, 'sparql/algebra/operator/str'
28
+ autoload :IsNumeric, 'sparql/algebra/operator/is_numeric'
29
+ autoload :IsURI, 'sparql/algebra/operator/is_iri'
30
+ autoload :IRI, 'sparql/algebra/operator/iri'
19
31
  autoload :Lang, 'sparql/algebra/operator/lang'
20
- autoload :Datatype, 'sparql/algebra/operator/datatype'
32
+ autoload :LCase, 'sparql/algebra/operator/lcase'
33
+ autoload :MD5, 'sparql/algebra/operator/md5'
34
+ autoload :Minus, 'sparql/algebra/operator/minus'
35
+ autoload :Minutes, 'sparql/algebra/operator/minutes'
36
+ autoload :Month, 'sparql/algebra/operator/month'
37
+ autoload :Not, 'sparql/algebra/operator/not'
38
+ autoload :Plus, 'sparql/algebra/operator/plus'
39
+ autoload :Round, 'sparql/algebra/operator/round'
40
+ autoload :Seconds, 'sparql/algebra/operator/seconds'
41
+ autoload :SHA1, 'sparql/algebra/operator/sha1'
42
+ autoload :SHA256, 'sparql/algebra/operator/sha256'
43
+ autoload :SHA512, 'sparql/algebra/operator/sha512'
44
+ autoload :Str, 'sparql/algebra/operator/str'
45
+ autoload :Timezone, 'sparql/algebra/operator/timezone'
46
+ autoload :TZ, 'sparql/algebra/operator/tz'
47
+ autoload :Year, 'sparql/algebra/operator/year'
21
48
 
22
49
  # Binary operators
23
- autoload :Or, 'sparql/algebra/operator/or'
50
+ autoload :Add, 'sparql/algebra/operator/add'
24
51
  autoload :And, 'sparql/algebra/operator/and'
25
52
  autoload :Compare, 'sparql/algebra/operator/compare'
53
+ autoload :Concat, 'sparql/algebra/operator/concat'
54
+ autoload :Contains, 'sparql/algebra/operator/contains'
55
+ autoload :Divide, 'sparql/algebra/operator/divide'
26
56
  autoload :Equal, 'sparql/algebra/operator/equal'
27
- autoload :Extend, 'sparql/algebra/operator/extend'
28
- autoload :NotEqual, 'sparql/algebra/operator/not_equal'
29
- autoload :LessThan, 'sparql/algebra/operator/less_than'
57
+ autoload :If, 'sparql/algebra/operator/if'
30
58
  autoload :GreaterThan, 'sparql/algebra/operator/greater_than'
31
- autoload :LessThanOrEqual, 'sparql/algebra/operator/less_than_or_equal'
32
59
  autoload :GreaterThanOrEqual, 'sparql/algebra/operator/greater_than_or_equal'
33
- autoload :Multiply, 'sparql/algebra/operator/multiply'
34
- autoload :Divide, 'sparql/algebra/operator/divide'
35
- autoload :Add, 'sparql/algebra/operator/add'
36
- autoload :Subtract, 'sparql/algebra/operator/subtract'
37
- autoload :SameTerm, 'sparql/algebra/operator/same_term'
38
60
  autoload :LangMatches, 'sparql/algebra/operator/lang_matches'
61
+ autoload :LessThan, 'sparql/algebra/operator/less_than'
62
+ autoload :LessThanOrEqual, 'sparql/algebra/operator/less_than_or_equal'
63
+ autoload :Multiply, 'sparql/algebra/operator/multiply'
64
+ autoload :NotEqual, 'sparql/algebra/operator/not_equal'
65
+ autoload :Or, 'sparql/algebra/operator/or'
39
66
  autoload :Regex, 'sparql/algebra/operator/regex'
67
+ autoload :Replace, 'sparql/algebra/operator/replace'
68
+ autoload :SameTerm, 'sparql/algebra/operator/same_term'
69
+ autoload :StrAfter, 'sparql/algebra/operator/strafter'
70
+ autoload :StrBefore, 'sparql/algebra/operator/strbefore'
71
+ autoload :StrDT, 'sparql/algebra/operator/strdt'
72
+ autoload :StrEnds, 'sparql/algebra/operator/strends'
73
+ autoload :StrLang, 'sparql/algebra/operator/strlang'
74
+ autoload :StrLen, 'sparql/algebra/operator/strlen'
75
+ autoload :StrStarts, 'sparql/algebra/operator/strstarts'
76
+ autoload :SubStr, 'sparql/algebra/operator/substr'
77
+ autoload :Subtract, 'sparql/algebra/operator/subtract'
78
+ autoload :UCase, 'sparql/algebra/operator/ucase'
40
79
 
41
80
  # Miscellaneous
42
81
  autoload :Asc, 'sparql/algebra/operator/asc'
82
+ autoload :Coalesce, 'sparql/algebra/operator/coalesce'
43
83
  autoload :Desc, 'sparql/algebra/operator/desc'
44
84
  autoload :Exprlist, 'sparql/algebra/operator/exprlist'
85
+ autoload :In, 'sparql/algebra/operator/in'
86
+ autoload :NotIn, 'sparql/algebra/operator/notin'
45
87
 
46
88
  # Query operators
47
89
  autoload :Ask, 'sparql/algebra/operator/ask'
@@ -51,6 +93,7 @@ module SPARQL; module Algebra
51
93
  autoload :Dataset, 'sparql/algebra/operator/dataset'
52
94
  autoload :Describe, 'sparql/algebra/operator/describe'
53
95
  autoload :Distinct, 'sparql/algebra/operator/distinct'
96
+ autoload :Extend, 'sparql/algebra/operator/extend'
54
97
  autoload :Filter, 'sparql/algebra/operator/filter'
55
98
  autoload :Graph, 'sparql/algebra/operator/graph'
56
99
  autoload :Join, 'sparql/algebra/operator/join'
@@ -71,66 +114,107 @@ module SPARQL; module Algebra
71
114
  def self.for(name, arity = nil)
72
115
  # TODO: refactor this to dynamically introspect loaded operator classes.
73
116
  case (name.to_s.downcase.to_sym rescue nil)
74
- when :<=> then Compare # non-standard
75
- when :'=' then Equal
76
- when :'!=' then NotEqual
77
- when :< then LessThan
78
- when :> then GreaterThan
79
- when :<= then LessThanOrEqual
80
- when :>= then GreaterThanOrEqual
81
- when :* then Multiply
82
- when :'/' then Divide
83
- when :+ then arity.eql?(1) ? Plus : Add
84
- when :- then arity.eql?(1) ? Minus : Subtract
85
- when :not, :'!' then Not
86
- when :plus then Plus
87
- when :minus then Minus
88
- when :bound then Bound
89
- when :isblank then IsBlank
90
- when :isiri then IsIRI
91
- when :isuri then IsIRI # alias
92
- when :isliteral then IsLiteral
93
- when :str then Str
94
- when :lang then Lang
95
- when :datatype then Datatype
96
- when :or, :'||' then Or
97
- when :and, :'&&' then And
98
- when :multiply then Multiply
99
- when :divide then Divide
100
- when :add then Add
101
- when :subtract then Subtract
102
- when :sameterm then SameTerm
103
- when :langmatches then LangMatches
104
- when :regex then Regex
105
-
117
+ when :'!=' then NotEqual
118
+ when :'/' then Divide
119
+ when :'=' then Equal
120
+ when :* then Multiply
121
+ when :+ then arity.eql?(1) ? Plus : Add
122
+ when :- then arity.eql?(1) ? Minus : Subtract
123
+ when :< then LessThan
124
+ when :<= then LessThanOrEqual
125
+ when :<=> then Compare # non-standard
126
+ when :> then GreaterThan
127
+ when :>= then GreaterThanOrEqual
128
+ when :abs then Abs
129
+ when :add then Add
130
+ when :and, :'&&' then And
131
+ when :bnode then BNode
132
+ when :bound then Bound
133
+ when :coalesce then Coalesce
134
+ when :ceil then Ceil
135
+ when :concat then Concat
136
+ when :contains then Contains
137
+ when :datatype then Datatype
138
+ when :day then Day
139
+ when :encode_for_uri then EncodeForURI
140
+ when :divide then Divide
141
+ when :floor then Floor
142
+ when :hours then Hours
143
+ when :if then If
144
+ when :in then In
145
+ when :iri, :uri then IRI
146
+ when :isblank then IsBlank
147
+ when :isiri then IsIRI
148
+ when :isliteral then IsLiteral
149
+ when :isnumeric then IsNumeric
150
+ when :isuri then IsIRI # alias
151
+ when :lang then Lang
152
+ when :langmatches then LangMatches
153
+ when :lcase then LCase
154
+ when :md5 then MD5
155
+ when :minus then Minus
156
+ when :minutes then Minutes
157
+ when :month then Month
158
+ when :multiply then Multiply
159
+ when :not, :'!' then Not
160
+ when :notin then NotIn
161
+ when :now then Now
162
+ when :or, :'||' then Or
163
+ when :plus then Plus
164
+ when :rand then Rand
165
+ when :regex then Regex
166
+ when :replace then Replace
167
+ when :round then Round
168
+ when :sameterm then SameTerm
169
+ when :seconds then Seconds
170
+ when :sha1 then SHA1
171
+ when :sha256 then SHA256
172
+ when :sha512 then SHA512
173
+ when :str then Str
174
+ when :strafter then StrAfter
175
+ when :strbefore then StrBefore
176
+ when :strdt then StrDT
177
+ when :strends then StrEnds
178
+ when :strlang then StrLang
179
+ when :strlen then StrLen
180
+ when :strstarts then StrStarts
181
+ when :struuid then StrUUID
182
+ when :substr then SubStr
183
+ when :subtract then Subtract
184
+ when :timezone then Timezone
185
+ when :tz then TZ
186
+ when :ucase then UCase
187
+ when :uuid then UUID
188
+ when :year then Year
189
+
106
190
  # Miscellaneous
107
- when :asc then Asc
108
- when :desc then Desc
109
- when :exprlist then Exprlist
191
+ when :asc then Asc
192
+ when :desc then Desc
193
+ when :exprlist then Exprlist
110
194
 
111
195
  # Datasets
112
- when :dataset then Dataset
196
+ when :dataset then Dataset
113
197
 
114
198
  # Query forms
115
- when :ask then Ask
116
- when :base then Base
117
- when :bgp then BGP
118
- when :construct then Construct
119
- when :describe then Describe
120
- when :distinct then Distinct
121
- when :extend then Extend
122
- when :filter then Filter
123
- when :graph then Graph
124
- when :join then Join
125
- when :leftjoin then LeftJoin
126
- when :order then Order
127
- when :prefix then Prefix
128
- when :project then Project
129
- when :reduced then Reduced
130
- when :slice then Slice
131
- when :triple then RDF::Query::Pattern
132
- when :union then Union
133
- else nil # not found
199
+ when :ask then Ask
200
+ when :base then Base
201
+ when :bgp then BGP
202
+ when :construct then Construct
203
+ when :describe then Describe
204
+ when :distinct then Distinct
205
+ when :extend then Extend
206
+ when :filter then Filter
207
+ when :graph then Graph
208
+ when :join then Join
209
+ when :leftjoin then LeftJoin
210
+ when :order then Order
211
+ when :prefix then Prefix
212
+ when :project then Project
213
+ when :reduced then Reduced
214
+ when :slice then Slice
215
+ when :triple then RDF::Query::Pattern
216
+ when :union then Union
217
+ else nil # not found
134
218
  end
135
219
  end
136
220
 
@@ -398,28 +482,29 @@ module SPARQL; module Algebra
398
482
  case literal
399
483
  when FalseClass then RDF::Literal::FALSE
400
484
  when TrueClass then RDF::Literal::TRUE
401
- # If the argument is a typed literal with a datatype of
402
- # `xsd:boolean`, the EBV is the value of that argument.
403
- # However, the EBV of any literal whose type is `xsd:boolean` is
404
- # false if the lexical form is not valid for that datatype.
405
485
  when RDF::Literal::Boolean
486
+ # If the argument is a typed literal with a datatype of
487
+ # `xsd:boolean`, the EBV is the value of that argument.
488
+ # However, the EBV of any literal whose type is `xsd:boolean` is
489
+ # false if the lexical form is not valid for that datatype.
406
490
  RDF::Literal(literal.valid? && literal.true?)
407
- # If the argument is a numeric type or a typed literal with a
408
- # datatype derived from a numeric type, the EBV is false if the
409
- # operand value is NaN or is numerically equal to zero; otherwise
410
- # the EBV is true.
411
- # However, the EBV of any literal whose type is numeric is
412
- # false if the lexical form is not valid for that datatype.
413
491
  when RDF::Literal::Numeric
492
+ # If the argument is a numeric type or a typed literal with a
493
+ # datatype derived from a numeric type, the EBV is false if the
494
+ # operand value is NaN or is numerically equal to zero; otherwise
495
+ # the EBV is true.
496
+ # However, the EBV of any literal whose type is numeric is
497
+ # false if the lexical form is not valid for that datatype.
414
498
  RDF::Literal(literal.valid? && !(literal.zero?) && !(literal.respond_to?(:nan?) && literal.nan?))
415
- # If the argument is a plain literal or a typed literal with a
416
- # datatype of `xsd:string`, the EBV is false if the operand value
417
- # has zero length; otherwise the EBV is true.
418
499
  else case
419
- when literal.is_a?(RDF::Literal) && (literal.plain? || literal.datatype.eql?(RDF::XSD.string))
500
+ when literal.is_a?(RDF::Literal) && literal.plain?
501
+ # If the argument is a plain literal or a typed literal with a
502
+ # datatype of `xsd:string`, the EBV is false if the operand value
503
+ # has zero length; otherwise the EBV is true.
420
504
  RDF::Literal(!(literal.value.empty?))
421
- # All other arguments, including unbound arguments, produce a type error.
422
- else raise TypeError, "could not coerce #{literal.inspect} to an RDF::Literal::Boolean"
505
+ else
506
+ # All other arguments, including unbound arguments, produce a type error.
507
+ raise TypeError, "could not coerce #{literal.inspect} to an RDF::Literal::Boolean"
423
508
  end
424
509
  end
425
510
  end
@@ -536,5 +621,30 @@ module SPARQL; module Algebra
536
621
  super
537
622
  end
538
623
  end # Ternary
624
+
625
+ ##
626
+ # A SPARQL quaternary operator.
627
+ #
628
+ # Operators of this kind take four operands.
629
+ #
630
+ # @abstract
631
+ class Quaternary < Operator
632
+ ARITY = 4
633
+
634
+ ##
635
+ # @param [RDF::Term] arg1
636
+ # the first operand
637
+ # @param [RDF::Term] arg2
638
+ # the second operand
639
+ # @param [RDF::Term] arg3
640
+ # the third operand
641
+ # @param [RDF::Term] arg4
642
+ # the forth operand
643
+ # @param [Hash{Symbol => Object}] options
644
+ # any additional options (see {Operator#initialize})
645
+ def initialize(arg1, arg2, arg3, arg4, options = {})
646
+ super
647
+ end
648
+ end # Ternary
539
649
  end # Operator
540
650
  end; end # SPARQL::Algebra