sparql 1.0.6 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
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