openlogic-rdf 0.3.6

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 (80) hide show
  1. data/AUTHORS +3 -0
  2. data/CREDITS +9 -0
  3. data/README +361 -0
  4. data/UNLICENSE +24 -0
  5. data/VERSION +1 -0
  6. data/bin/rdf +18 -0
  7. data/etc/doap.nt +62 -0
  8. data/lib/df.rb +1 -0
  9. data/lib/rdf/cli.rb +200 -0
  10. data/lib/rdf/format.rb +383 -0
  11. data/lib/rdf/mixin/countable.rb +39 -0
  12. data/lib/rdf/mixin/durable.rb +31 -0
  13. data/lib/rdf/mixin/enumerable.rb +637 -0
  14. data/lib/rdf/mixin/indexable.rb +26 -0
  15. data/lib/rdf/mixin/inferable.rb +5 -0
  16. data/lib/rdf/mixin/mutable.rb +191 -0
  17. data/lib/rdf/mixin/queryable.rb +265 -0
  18. data/lib/rdf/mixin/readable.rb +15 -0
  19. data/lib/rdf/mixin/type_check.rb +21 -0
  20. data/lib/rdf/mixin/writable.rb +152 -0
  21. data/lib/rdf/model/graph.rb +263 -0
  22. data/lib/rdf/model/list.rb +731 -0
  23. data/lib/rdf/model/literal/boolean.rb +121 -0
  24. data/lib/rdf/model/literal/date.rb +73 -0
  25. data/lib/rdf/model/literal/datetime.rb +72 -0
  26. data/lib/rdf/model/literal/decimal.rb +86 -0
  27. data/lib/rdf/model/literal/double.rb +189 -0
  28. data/lib/rdf/model/literal/integer.rb +126 -0
  29. data/lib/rdf/model/literal/numeric.rb +184 -0
  30. data/lib/rdf/model/literal/time.rb +87 -0
  31. data/lib/rdf/model/literal/token.rb +47 -0
  32. data/lib/rdf/model/literal/xml.rb +39 -0
  33. data/lib/rdf/model/literal.rb +373 -0
  34. data/lib/rdf/model/node.rb +156 -0
  35. data/lib/rdf/model/resource.rb +28 -0
  36. data/lib/rdf/model/statement.rb +296 -0
  37. data/lib/rdf/model/term.rb +77 -0
  38. data/lib/rdf/model/uri.rb +570 -0
  39. data/lib/rdf/model/value.rb +133 -0
  40. data/lib/rdf/nquads.rb +152 -0
  41. data/lib/rdf/ntriples/format.rb +48 -0
  42. data/lib/rdf/ntriples/reader.rb +239 -0
  43. data/lib/rdf/ntriples/writer.rb +219 -0
  44. data/lib/rdf/ntriples.rb +104 -0
  45. data/lib/rdf/query/pattern.rb +329 -0
  46. data/lib/rdf/query/solution.rb +252 -0
  47. data/lib/rdf/query/solutions.rb +237 -0
  48. data/lib/rdf/query/variable.rb +221 -0
  49. data/lib/rdf/query.rb +404 -0
  50. data/lib/rdf/reader.rb +511 -0
  51. data/lib/rdf/repository.rb +389 -0
  52. data/lib/rdf/transaction.rb +161 -0
  53. data/lib/rdf/util/aliasing.rb +63 -0
  54. data/lib/rdf/util/cache.rb +139 -0
  55. data/lib/rdf/util/file.rb +38 -0
  56. data/lib/rdf/util/uuid.rb +36 -0
  57. data/lib/rdf/util.rb +6 -0
  58. data/lib/rdf/version.rb +19 -0
  59. data/lib/rdf/vocab/cc.rb +18 -0
  60. data/lib/rdf/vocab/cert.rb +13 -0
  61. data/lib/rdf/vocab/dc.rb +63 -0
  62. data/lib/rdf/vocab/dc11.rb +23 -0
  63. data/lib/rdf/vocab/doap.rb +45 -0
  64. data/lib/rdf/vocab/exif.rb +168 -0
  65. data/lib/rdf/vocab/foaf.rb +69 -0
  66. data/lib/rdf/vocab/geo.rb +13 -0
  67. data/lib/rdf/vocab/http.rb +26 -0
  68. data/lib/rdf/vocab/owl.rb +59 -0
  69. data/lib/rdf/vocab/rdfs.rb +17 -0
  70. data/lib/rdf/vocab/rsa.rb +12 -0
  71. data/lib/rdf/vocab/rss.rb +14 -0
  72. data/lib/rdf/vocab/sioc.rb +93 -0
  73. data/lib/rdf/vocab/skos.rb +36 -0
  74. data/lib/rdf/vocab/wot.rb +21 -0
  75. data/lib/rdf/vocab/xhtml.rb +9 -0
  76. data/lib/rdf/vocab/xsd.rb +58 -0
  77. data/lib/rdf/vocab.rb +215 -0
  78. data/lib/rdf/writer.rb +475 -0
  79. data/lib/rdf.rb +192 -0
  80. metadata +173 -0
@@ -0,0 +1,121 @@
1
+ module RDF; class Literal
2
+ ##
3
+ # A boolean literal.
4
+ #
5
+ # @see http://www.w3.org/TR/xmlschema-2/#boolean
6
+ # @since 0.2.1
7
+ class Boolean < Literal
8
+ DATATYPE = XSD.boolean
9
+ GRAMMAR = /^(true|false|1|0)$/i.freeze
10
+ TRUES = %w(true 1).freeze
11
+ FALSES = %w(false 0).freeze
12
+
13
+ ##
14
+ # @param [Boolean] value
15
+ # @option options [String] :lexical (nil)
16
+ def initialize(value, options = {})
17
+ @datatype = RDF::URI(options[:datatype] || self.class.const_get(:DATATYPE))
18
+ @string = options[:lexical] if options.has_key?(:lexical)
19
+ @string ||= value if value.is_a?(String)
20
+ @object = case
21
+ when true.equal?(value) then true
22
+ when false.equal?(value) then false
23
+ when TRUES.include?(value.to_s.downcase) then true
24
+ when FALSES.include?(value.to_s.downcase) then false
25
+ else value
26
+ end
27
+ end
28
+
29
+ ##
30
+ # Converts this literal into its canonical lexical representation.
31
+ #
32
+ # @return [RDF::Literal] `self`
33
+ # @see http://www.w3.org/TR/xmlschema-2/#boolean-canonical-representation
34
+ def canonicalize!
35
+ @string = (@object ? :true : :false).to_s
36
+ self
37
+ end
38
+
39
+ ##
40
+ # Compares this literal to `other` for sorting purposes.
41
+ #
42
+ # @param [Object] other
43
+ # @return [Integer] `-1`, `0`, or `1`
44
+ # @since 0.3.0
45
+ def <=>(other)
46
+ case other
47
+ when TrueClass, FalseClass
48
+ to_i <=> (other ? 1 : 0)
49
+ when RDF::Literal::Boolean
50
+ to_i <=> other.to_i
51
+ else super
52
+ end
53
+ end
54
+
55
+ ##
56
+ # Returns `true` if this literal is equivalent to `other`.
57
+ #
58
+ # @param [Object] other
59
+ # @return [Boolean] `true` or `false`
60
+ # @since 0.3.0
61
+ def ==(other)
62
+ # If lexically invalid, use regular literal testing
63
+ return super unless self.valid?
64
+
65
+ other = Literal::Boolean.new(other) if other.class == TrueClass || other.class == FalseClass
66
+
67
+ case other
68
+ when Literal::Boolean
69
+ return super unless other.valid?
70
+ (cmp = (self <=> other)) ? cmp.zero? : false
71
+ else
72
+ super
73
+ end
74
+ end
75
+
76
+ ##
77
+ # Returns the value as a string.
78
+ #
79
+ # @return [String]
80
+ def to_s
81
+ @string || @object.to_s
82
+ end
83
+
84
+ ##
85
+ # Returns the value as an integer.
86
+ #
87
+ # @return [Integer] `0` or `1`
88
+ # @since 0.3.0
89
+ def to_i
90
+ @object ? 1 : 0
91
+ end
92
+
93
+ ##
94
+ # Returns `true` if this value is `true`.
95
+ #
96
+ # @return [Boolean]
97
+ def true?
98
+ @object.equal?(true)
99
+ end
100
+
101
+ ##
102
+ # Returns `true` if this value is `false`.
103
+ #
104
+ # @return [Boolean]
105
+ def false?
106
+ @object.equal?(false)
107
+ end
108
+
109
+ ##
110
+ # Returns a developer-friendly representation of `self`.
111
+ #
112
+ # @return [String]
113
+ def inspect
114
+ case
115
+ when self.equal?(RDF::Literal::TRUE) then 'RDF::Literal::TRUE'
116
+ when self.equal?(RDF::Literal::FALSE) then 'RDF::Literal::FALSE'
117
+ else super
118
+ end
119
+ end
120
+ end # Boolean
121
+ end; end # RDF::Literal
@@ -0,0 +1,73 @@
1
+ module RDF; class Literal
2
+ ##
3
+ # A date literal.
4
+ #
5
+ # @see http://www.w3.org/TR/xmlschema-2/#date
6
+ # @since 0.2.1
7
+ class Date < Literal
8
+ DATATYPE = XSD.date
9
+ GRAMMAR = %r(\A-?\d{4}-\d{2}-\d{2}(([\+\-]\d{2}:\d{2})|UTC|Z)?\Z).freeze
10
+ FORMAT = '%Y-%m-%d%Z'.freeze
11
+
12
+ ##
13
+ # @param [Date] value
14
+ # @option options [String] :lexical (nil)
15
+ def initialize(value, options = {})
16
+ @datatype = RDF::URI(options[:datatype] || self.class.const_get(:DATATYPE))
17
+ @string = options[:lexical] if options.has_key?(:lexical)
18
+ @string ||= value if value.is_a?(String)
19
+ @object = case
20
+ when value.is_a?(::Date) then value
21
+ when value.respond_to?(:to_date) then value.to_date # Ruby 1.9+
22
+ else ::Date.parse(value.to_s)
23
+ end rescue nil
24
+ end
25
+
26
+ ##
27
+ # Converts this literal into its canonical lexical representation.
28
+ #
29
+ # @return [RDF::Literal] `self`
30
+ # @see http://www.w3.org/TR/xmlschema-2/#date
31
+ def canonicalize!
32
+ @string = @object.strftime(FORMAT).sub(/\+00:00|UTC/, 'Z') if self.valid?
33
+ self
34
+ end
35
+
36
+ ##
37
+ # Returns `true` if the value adheres to the defined grammar of the
38
+ # datatype.
39
+ #
40
+ # Special case for date and dateTime, for which '0000' is not a valid year
41
+ #
42
+ # @return [Boolean]
43
+ # @since 0.2.1
44
+ def valid?
45
+ super && object && value !~ %r(\A0000)
46
+ end
47
+
48
+ ##
49
+ # Returns the value as a string.
50
+ #
51
+ # @return [String]
52
+ def to_s
53
+ @string || @object.strftime(FORMAT).sub(/\+00:00|UTC/, 'Z')
54
+ end
55
+
56
+ ##
57
+ # Equal compares as Date objects
58
+ def ==(other)
59
+ # If lexically invalid, use regular literal testing
60
+ return super unless self.valid?
61
+
62
+ case other
63
+ when Literal::Date
64
+ return super unless other.valid?
65
+ self.object == other.object
66
+ when Literal::Time, Literal::DateTime
67
+ false
68
+ else
69
+ super
70
+ end
71
+ end
72
+ end # Date
73
+ end; end # RDF::Literal
@@ -0,0 +1,72 @@
1
+ module RDF; class Literal
2
+ ##
3
+ # A date/time literal.
4
+ #
5
+ # @see http://www.w3.org/TR/xmlschema-2/#dateTime
6
+ # @since 0.2.1
7
+ class DateTime < Literal
8
+ DATATYPE = XSD.dateTime
9
+ GRAMMAR = %r(\A-?\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(([\+\-]\d{2}:\d{2})|UTC|Z)?\Z).freeze
10
+
11
+ ##
12
+ # @param [DateTime] value
13
+ # @option options [String] :lexical (nil)
14
+ def initialize(value, options = {})
15
+ @datatype = RDF::URI(options[:datatype] || self.class.const_get(:DATATYPE))
16
+ @string = options[:lexical] if options.has_key?(:lexical)
17
+ @string ||= value if value.is_a?(String)
18
+ @object = case
19
+ when value.is_a?(::DateTime) then value
20
+ when value.respond_to?(:to_datetime) then value.to_datetime # Ruby 1.9+
21
+ else ::DateTime.parse(value.to_s)
22
+ end rescue nil
23
+ end
24
+
25
+ ##
26
+ # Converts this literal into its canonical lexical representation.
27
+ #
28
+ # @return [RDF::Literal] `self`
29
+ # @see http://www.w3.org/TR/xmlschema-2/#dateTime
30
+ def canonicalize!
31
+ @string = @object.new_offset(0).strftime('%Y-%m-%dT%H:%M:%S%Z').sub(/\+00:00|UTC/, 'Z') if self.valid?
32
+ self
33
+ end
34
+
35
+ ##
36
+ # Returns `true` if the value adheres to the defined grammar of the
37
+ # datatype.
38
+ #
39
+ # Special case for date and dateTime, for which '0000' is not a valid year
40
+ #
41
+ # @return [Boolean]
42
+ # @since 0.2.1
43
+ def valid?
44
+ super && object && value !~ %r(\A0000)
45
+ end
46
+
47
+ ##
48
+ # Returns the value as a string.
49
+ #
50
+ # @return [String]
51
+ def to_s
52
+ @string || @object.strftime('%Y-%m-%dT%H:%M:%S%Z').sub(/\+00:00|UTC/, 'Z')
53
+ end
54
+
55
+ ##
56
+ # Equal compares as DateTime objects
57
+ def ==(other)
58
+ # If lexically invalid, use regular literal testing
59
+ return super unless self.valid?
60
+
61
+ case other
62
+ when Literal::DateTime
63
+ return super unless other.valid?
64
+ self.object == other.object
65
+ when Literal::Time, Literal::Date
66
+ false
67
+ else
68
+ super
69
+ end
70
+ end
71
+ end # DateTime
72
+ end; end # RDF::Literal
@@ -0,0 +1,86 @@
1
+ module RDF; class Literal
2
+ ##
3
+ # A decimal literal.
4
+ #
5
+ # @example Arithmetic with decimal literals
6
+ # RDF::Literal(BigDecimal('1.0')) + 0.5 #=> RDF::Literal(BigDecimal('1.5'))
7
+ # RDF::Literal(BigDecimal('1.0')) - 0.5 #=> RDF::Literal(BigDecimal('0.5'))
8
+ # RDF::Literal(BigDecimal('1.0')) * 0.5 #=> RDF::Literal(BigDecimal('0.5'))
9
+ # RDF::Literal(BigDecimal('1.0')) / 0.5 #=> RDF::Literal(BigDecimal('2.0'))
10
+ #
11
+ # @see http://www.w3.org/TR/xmlschema-2/#decimal
12
+ # @since 0.2.1
13
+ class Decimal < Numeric
14
+ DATATYPE = XSD.decimal
15
+ GRAMMAR = /^[\+\-]?\d+(\.\d*)?$/.freeze
16
+
17
+ ##
18
+ # @param [BigDecimal] value
19
+ # @option options [String] :lexical (nil)
20
+ def initialize(value, options = {})
21
+ @datatype = RDF::URI(options[:datatype] || self.class.const_get(:DATATYPE))
22
+ @string = options[:lexical] if options.has_key?(:lexical)
23
+ @string ||= value if value.is_a?(String)
24
+ @object = case
25
+ when value.is_a?(BigDecimal) then value
26
+ else BigDecimal(value.to_s)
27
+ end
28
+ end
29
+
30
+ ##
31
+ # Converts this literal into its canonical lexical representation.
32
+ #
33
+ # @return [RDF::Literal] `self`
34
+ # @see http://www.w3.org/TR/xmlschema-2/#decimal
35
+ def canonicalize!
36
+ # Can't use simple %f transformation due to special requirements from
37
+ # N3 tests in representation
38
+ @string = begin
39
+ i, f = @object.to_s('F').split('.')
40
+ i.sub!(/^\+?0+(\d)$/, '\1') # remove the optional leading '+' sign and any extra leading zeroes
41
+ f = f[0, 16] # truncate the fractional part after 15 decimal places
42
+ f.sub!(/0*$/, '') # remove any trailing zeroes
43
+ f = '0' if f.empty? # ...but there must be a digit to the right of the decimal point
44
+ "#{i}.#{f}"
45
+ end
46
+ @object = BigDecimal(@string) unless @object.nil?
47
+ self
48
+ end
49
+
50
+ ##
51
+ # Returns the absolute value of `self`.
52
+ #
53
+ # @return [RDF::Literal]
54
+ # @since 0.2.3
55
+ def abs
56
+ (d = to_d) && d > 0 ? self : RDF::Literal(d.abs)
57
+ end
58
+
59
+ ##
60
+ # Returns `true` if the value is zero.
61
+ #
62
+ # @return [Boolean]
63
+ # @since 0.2.3
64
+ def zero?
65
+ to_d.zero?
66
+ end
67
+
68
+ ##
69
+ # Returns `self` if the value is not zero, `nil` otherwise.
70
+ #
71
+ # @return [Boolean]
72
+ # @since 0.2.3
73
+ def nonzero?
74
+ to_d.nonzero? ? self : nil
75
+ end
76
+
77
+ ##
78
+ # Returns the value as a string.
79
+ #
80
+ # @return [String]
81
+ # @see BigDecimal#to_s
82
+ def to_s
83
+ @string || @object.to_s('F')
84
+ end
85
+ end # Decimal
86
+ end; end # RDF::Literal
@@ -0,0 +1,189 @@
1
+ module RDF; class Literal
2
+ ##
3
+ # An floating point number literal.
4
+ #
5
+ # @example Arithmetic with floating point literals
6
+ # RDF::Literal(1.0) + 0.5 #=> RDF::Literal(1.5)
7
+ # RDF::Literal(3.0) - 6 #=> RDF::Literal(-3.0)
8
+ # RDF::Literal(Math::PI) * 2 #=> RDF::Literal(Math::PI * 2)
9
+ # RDF::Literal(Math::PI) / 2 #=> RDF::Literal(Math::PI / 2)
10
+ #
11
+ # @see http://www.w3.org/TR/xmlschema-2/#double
12
+ # @since 0.2.1
13
+ class Double < Numeric
14
+ DATATYPE = XSD.double
15
+ GRAMMAR = /^NaN|(?:[\+\-]?(?:INF|(?:\d+(\.\d*)?([eE][\+\-]?\d+)?)))$/.freeze
16
+
17
+ ##
18
+ # @param [Float, #to_f] value
19
+ # @option options [String] :lexical (nil)
20
+ def initialize(value, options = {})
21
+ @datatype = RDF::URI(options[:datatype] || self.class.const_get(:DATATYPE))
22
+ @string = options[:lexical] if options.has_key?(:lexical)
23
+ @string ||= value if value.is_a?(String)
24
+ @object = case
25
+ when value.is_a?(::String) then case value
26
+ when 'INF' then 1/0.0
27
+ when '-INF' then -1/0.0
28
+ when 'NaN' then 0/0.0
29
+ else Float(value) rescue nil
30
+ end
31
+ when value.is_a?(::Float) then value
32
+ when value.respond_to?(:to_f) then value.to_f
33
+ else Float(value.to_s) rescue nil # FIXME
34
+ end
35
+ end
36
+
37
+ ##
38
+ # Converts this literal into its canonical lexical representation.
39
+ #
40
+ # @return [RDF::Literal] `self`
41
+ # @see http://www.w3.org/TR/xmlschema-2/#double
42
+ def canonicalize!
43
+ # Can't use simple %f transformation due to special requirements from
44
+ # N3 tests in representation
45
+ @string = case
46
+ when @object.nan? then 'NaN'
47
+ when @object.infinite? then @object.to_s[0...-'inity'.length].upcase
48
+ when @object.zero? then '0.0E0'
49
+ else
50
+ i, f, e = ('%.16E' % @object.to_f).split(/[\.E]/)
51
+ f.sub!(/0*$/, '') # remove any trailing zeroes
52
+ f = '0' if f.empty? # ...but there must be a digit to the right of the decimal point
53
+ e.sub!(/^\+?0+(\d)$/, '\1') # remove the optional leading '+' sign and any extra leading zeroes
54
+ "#{i}.#{f}E#{e}"
55
+ end
56
+ @object = Float(@string) unless @object.nil?
57
+ self
58
+ end
59
+
60
+ ##
61
+ # Compares this literal to `other` for sorting purposes.
62
+ #
63
+ # @param [Object] other
64
+ # @return [Integer] `-1`, `0`, or `1`
65
+ # @since 0.3.0
66
+ def <=>(other)
67
+ case other
68
+ when ::Numeric
69
+ to_d <=> other
70
+ when RDF::Literal::Decimal, RDF::Literal::Double
71
+ to_d <=> other.to_d
72
+ else super
73
+ end
74
+ end
75
+
76
+ ##
77
+ # Returns `true` if the value is an invalid IEEE floating point number.
78
+ #
79
+ # @example
80
+ # RDF::Literal(-1.0).nan? #=> false
81
+ # RDF::Literal(1.0/0.0).nan? #=> false
82
+ # RDF::Literal(0.0/0.0).nan? #=> true
83
+ #
84
+ # @return [Boolean]
85
+ # @since 0.2.3
86
+ def nan?
87
+ to_f.nan?
88
+ end
89
+
90
+ ##
91
+ # Returns `true` if the value is a valid IEEE floating point number (it
92
+ # is not infinite, and `nan?` is `false`).
93
+ #
94
+ # @example
95
+ # RDF::Literal(-1.0).finite? #=> true
96
+ # RDF::Literal(1.0/0.0).finite? #=> false
97
+ # RDF::Literal(0.0/0.0).finite? #=> false
98
+ #
99
+ # @return [Boolean]
100
+ # @since 0.2.3
101
+ def finite?
102
+ to_f.finite?
103
+ end
104
+
105
+ ##
106
+ # Returns `nil`, `-1`, or `+1` depending on whether the value is finite,
107
+ # `-INF`, or `+INF`.
108
+ #
109
+ # @example
110
+ # RDF::Literal(0.0/0.0).infinite? #=> nil
111
+ # RDF::Literal(-1.0/0.0).infinite? #=> -1
112
+ # RDF::Literal(+1.0/0.0).infinite? #=> 1
113
+ #
114
+ # @return [Integer]
115
+ # @since 0.2.3
116
+ def infinite?
117
+ to_f.infinite?
118
+ end
119
+
120
+ ##
121
+ # Returns the smallest integer greater than or equal to `self`.
122
+ #
123
+ # @example
124
+ # RDF::Literal(1.2).ceil #=> RDF::Literal(2)
125
+ # RDF::Literal(-1.2).ceil #=> RDF::Literal(-1)
126
+ # RDF::Literal(2.0).ceil #=> RDF::Literal(2)
127
+ # RDF::Literal(-2.0).ceil #=> RDF::Literal(-2)
128
+ #
129
+ # @return [RDF::Literal]
130
+ # @since 0.2.3
131
+ def ceil
132
+ RDF::Literal(to_f.ceil)
133
+ end
134
+
135
+ ##
136
+ # Returns the largest integer less than or equal to `self`.
137
+ #
138
+ # @example
139
+ # RDF::Literal(1.2).floor #=> RDF::Literal(1)
140
+ # RDF::Literal(-1.2).floor #=> RDF::Literal(-2)
141
+ # RDF::Literal(2.0).floor #=> RDF::Literal(2)
142
+ # RDF::Literal(-2.0).floor #=> RDF::Literal(-2)
143
+ #
144
+ # @return [RDF::Literal]
145
+ # @since 0.2.3
146
+ def floor
147
+ RDF::Literal(to_f.floor)
148
+ end
149
+
150
+ ##
151
+ # Returns the absolute value of `self`.
152
+ #
153
+ # @return [RDF::Literal]
154
+ # @since 0.2.3
155
+ def abs
156
+ (f = to_f) && f > 0 ? self : RDF::Literal(f.abs)
157
+ end
158
+
159
+ ##
160
+ # Returns `true` if the value is zero.
161
+ #
162
+ # @return [Boolean]
163
+ # @since 0.2.3
164
+ def zero?
165
+ to_f.zero?
166
+ end
167
+
168
+ ##
169
+ # Returns `self` if the value is not zero, `nil` otherwise.
170
+ #
171
+ # @return [Boolean]
172
+ # @since 0.2.3
173
+ def nonzero?
174
+ to_f.nonzero? ? self : nil
175
+ end
176
+
177
+ ##
178
+ # Returns the value as a string.
179
+ #
180
+ # @return [String]
181
+ def to_s
182
+ @string || case
183
+ when @object.nan? then 'NaN'
184
+ when @object.infinite? then @object.to_s[0...-'inity'.length].upcase
185
+ else @object.to_s
186
+ end
187
+ end
188
+ end # Double
189
+ end; end # RDF::Literal
@@ -0,0 +1,126 @@
1
+ module RDF; class Literal
2
+ ##
3
+ # An integer literal.
4
+ #
5
+ # @example Arithmetic with integer literals
6
+ # RDF::Literal(40) + 2 #=> RDF::Literal(42)
7
+ # RDF::Literal(45) - 3 #=> RDF::Literal(42)
8
+ # RDF::Literal(6) * 7 #=> RDF::Literal(42)
9
+ # RDF::Literal(84) / 2 #=> RDF::Literal(42)
10
+ #
11
+ # @see http://www.w3.org/TR/xmlschema-2/#integer
12
+ # @see http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#integer
13
+ # @since 0.2.1
14
+ class Integer < Decimal
15
+ DATATYPE = XSD.integer
16
+ GRAMMAR = /^[\+\-]?\d+$/.freeze
17
+
18
+ ##
19
+ # @param [Integer, #to_i] value
20
+ # @option options [String] :lexical (nil)
21
+ def initialize(value, options = {})
22
+ @datatype = RDF::URI(options[:datatype] || self.class.const_get(:DATATYPE))
23
+ @string = options[:lexical] if options.has_key?(:lexical)
24
+ @string ||= value if value.is_a?(String)
25
+ @object = case
26
+ when value.is_a?(::String) then Integer(value) rescue nil
27
+ when value.is_a?(::Integer) then value
28
+ when value.respond_to?(:to_i) then value.to_i
29
+ else Integer(value.to_s) rescue nil
30
+ end
31
+ end
32
+
33
+ ##
34
+ # Converts this literal into its canonical lexical representation.
35
+ #
36
+ # @return [RDF::Literal] `self`
37
+ # @see http://www.w3.org/TR/xmlschema-2/#integer
38
+ def canonicalize!
39
+ @string = @object.to_s if @object
40
+ self
41
+ end
42
+
43
+ ##
44
+ # Returns the successor value of `self`.
45
+ #
46
+ # @return [RDF::Literal]
47
+ # @since 0.2.3
48
+ def pred
49
+ RDF::Literal(to_i.pred)
50
+ end
51
+
52
+ ##
53
+ # Returns the predecessor value of `self`.
54
+ #
55
+ # @return [RDF::Literal]
56
+ # @since 0.2.3
57
+ def succ
58
+ RDF::Literal(to_i.succ)
59
+ end
60
+ alias_method :next, :succ
61
+
62
+ ##
63
+ # Returns `true` if the value is even.
64
+ #
65
+ # @return [Boolean]
66
+ # @since 0.2.3
67
+ def even?
68
+ to_i.even?
69
+ end
70
+
71
+ ##
72
+ # Returns `true` if the value is odd.
73
+ #
74
+ # @return [Boolean]
75
+ # @since 0.2.3
76
+ def odd?
77
+ to_i.odd?
78
+ end
79
+
80
+ ##
81
+ # Returns the absolute value of `self`.
82
+ #
83
+ # @return [RDF::Literal]
84
+ # @since 0.2.3
85
+ def abs
86
+ (n = to_i) && n > 0 ? self : RDF::Literal(n.abs)
87
+ end
88
+
89
+ ##
90
+ # Returns `true` if the value is zero.
91
+ #
92
+ # @return [Boolean]
93
+ # @since 0.2.3
94
+ def zero?
95
+ to_i.zero?
96
+ end
97
+
98
+ ##
99
+ # Returns `self` if the value is not zero, `nil` otherwise.
100
+ #
101
+ # @return [Boolean]
102
+ # @since 0.2.3
103
+ def nonzero?
104
+ to_i.nonzero? ? self : nil
105
+ end
106
+
107
+ ##
108
+ # Returns the value as a string.
109
+ #
110
+ # @return [String]
111
+ def to_s
112
+ @string || @object.to_s
113
+ end
114
+
115
+ ##
116
+ # Returns the value as an `OpenSSL::BN` instance.
117
+ #
118
+ # @return [OpenSSL::BN]
119
+ # @see http://ruby-doc.org/stdlib/libdoc/openssl/rdoc/classes/OpenSSL/BN.html
120
+ # @since 0.2.4
121
+ def to_bn
122
+ require 'openssl' unless defined?(OpenSSL::BN)
123
+ OpenSSL::BN.new(to_s)
124
+ end
125
+ end # Integer
126
+ end; end # RDF::Literal