rdf-n3 3.1.1 → 3.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +148 -69
  3. data/UNLICENSE +1 -1
  4. data/VERSION +1 -1
  5. data/lib/rdf/n3.rb +8 -8
  6. data/lib/rdf/n3/algebra.rb +147 -68
  7. data/lib/rdf/n3/algebra/builtin.rb +79 -0
  8. data/lib/rdf/n3/algebra/formula.rb +355 -94
  9. data/lib/rdf/n3/algebra/list/append.rb +33 -4
  10. data/lib/rdf/n3/algebra/list/first.rb +24 -0
  11. data/lib/rdf/n3/algebra/list/in.rb +42 -3
  12. data/lib/rdf/n3/algebra/list/last.rb +17 -4
  13. data/lib/rdf/n3/algebra/list/length.rb +24 -0
  14. data/lib/rdf/n3/algebra/list/member.rb +39 -2
  15. data/lib/rdf/n3/algebra/list_operator.rb +83 -0
  16. data/lib/rdf/n3/algebra/log/conclusion.rb +57 -1
  17. data/lib/rdf/n3/algebra/log/conjunction.rb +28 -1
  18. data/lib/rdf/n3/algebra/log/content.rb +34 -0
  19. data/lib/rdf/n3/algebra/log/equal_to.rb +34 -0
  20. data/lib/rdf/n3/algebra/log/implies.rb +55 -30
  21. data/lib/rdf/n3/algebra/log/includes.rb +58 -1
  22. data/lib/rdf/n3/algebra/log/n3_string.rb +34 -0
  23. data/lib/rdf/n3/algebra/log/not_equal_to.rb +23 -0
  24. data/lib/rdf/n3/algebra/log/not_includes.rb +27 -0
  25. data/lib/rdf/n3/algebra/log/output_string.rb +40 -0
  26. data/lib/rdf/n3/algebra/log/parsed_as_n3.rb +36 -0
  27. data/lib/rdf/n3/algebra/log/semantics.rb +40 -0
  28. data/lib/rdf/n3/algebra/math/absolute_value.rb +36 -0
  29. data/lib/rdf/n3/algebra/math/acos.rb +26 -0
  30. data/lib/rdf/n3/algebra/math/acosh.rb +26 -0
  31. data/lib/rdf/n3/algebra/math/asin.rb +26 -0
  32. data/lib/rdf/n3/algebra/math/asinh.rb +26 -0
  33. data/lib/rdf/n3/algebra/math/atan.rb +26 -0
  34. data/lib/rdf/n3/algebra/math/atanh.rb +26 -0
  35. data/lib/rdf/n3/algebra/math/ceiling.rb +28 -0
  36. data/lib/rdf/n3/algebra/math/cos.rb +40 -0
  37. data/lib/rdf/n3/algebra/math/cosh.rb +38 -0
  38. data/lib/rdf/n3/algebra/math/difference.rb +34 -3
  39. data/lib/rdf/n3/algebra/math/equal_to.rb +54 -0
  40. data/lib/rdf/n3/algebra/math/exponentiation.rb +29 -3
  41. data/lib/rdf/n3/algebra/math/floor.rb +28 -0
  42. data/lib/rdf/n3/algebra/math/greater_than.rb +41 -0
  43. data/lib/rdf/n3/algebra/math/less_than.rb +41 -0
  44. data/lib/rdf/n3/algebra/math/negation.rb +31 -2
  45. data/lib/rdf/n3/algebra/math/not_equal_to.rb +25 -0
  46. data/lib/rdf/n3/algebra/math/not_greater_than.rb +25 -0
  47. data/lib/rdf/n3/algebra/math/not_less_than.rb +25 -0
  48. data/lib/rdf/n3/algebra/math/product.rb +14 -3
  49. data/lib/rdf/n3/algebra/math/quotient.rb +30 -3
  50. data/lib/rdf/n3/algebra/math/remainder.rb +29 -3
  51. data/lib/rdf/n3/algebra/math/rounded.rb +20 -3
  52. data/lib/rdf/n3/algebra/math/sin.rb +40 -0
  53. data/lib/rdf/n3/algebra/math/sinh.rb +38 -0
  54. data/lib/rdf/n3/algebra/math/sum.rb +35 -4
  55. data/lib/rdf/n3/algebra/math/tan.rb +40 -0
  56. data/lib/rdf/n3/algebra/math/tanh.rb +38 -0
  57. data/lib/rdf/n3/algebra/not_implemented.rb +13 -0
  58. data/lib/rdf/n3/algebra/resource_operator.rb +123 -0
  59. data/lib/rdf/n3/algebra/str/concatenation.rb +21 -3
  60. data/lib/rdf/n3/algebra/str/contains.rb +28 -4
  61. data/lib/rdf/n3/algebra/str/contains_ignoring_case.rb +33 -0
  62. data/lib/rdf/n3/algebra/str/ends_with.rb +33 -0
  63. data/lib/rdf/n3/algebra/str/equal_ignoring_case.rb +34 -0
  64. data/lib/rdf/n3/algebra/str/format.rb +12 -4
  65. data/lib/rdf/n3/algebra/str/greater_than.rb +38 -0
  66. data/lib/rdf/n3/algebra/str/less_than.rb +33 -0
  67. data/lib/rdf/n3/algebra/str/matches.rb +33 -5
  68. data/lib/rdf/n3/algebra/str/not_equal_ignoring_case.rb +17 -0
  69. data/lib/rdf/n3/algebra/str/not_greater_than.rb +17 -0
  70. data/lib/rdf/n3/algebra/str/not_less_than.rb +17 -0
  71. data/lib/rdf/n3/algebra/str/not_matches.rb +18 -0
  72. data/lib/rdf/n3/algebra/str/replace.rb +28 -5
  73. data/lib/rdf/n3/algebra/str/scrape.rb +31 -5
  74. data/lib/rdf/n3/algebra/str/starts_with.rb +33 -0
  75. data/lib/rdf/n3/algebra/time/day.rb +35 -0
  76. data/lib/rdf/n3/algebra/time/day_of_week.rb +27 -0
  77. data/lib/rdf/n3/algebra/time/gm_time.rb +29 -0
  78. data/lib/rdf/n3/algebra/time/hour.rb +35 -0
  79. data/lib/rdf/n3/algebra/time/in_seconds.rb +59 -0
  80. data/lib/rdf/n3/algebra/time/local_time.rb +29 -0
  81. data/lib/rdf/n3/algebra/time/minute.rb +35 -0
  82. data/lib/rdf/n3/algebra/time/month.rb +35 -0
  83. data/lib/rdf/n3/algebra/time/second.rb +35 -0
  84. data/lib/rdf/n3/algebra/time/timezone.rb +36 -0
  85. data/lib/rdf/n3/algebra/time/year.rb +29 -0
  86. data/lib/rdf/n3/extensions.rb +180 -21
  87. data/lib/rdf/n3/format.rb +65 -0
  88. data/lib/rdf/n3/list.rb +630 -0
  89. data/lib/rdf/n3/reader.rb +762 -485
  90. data/lib/rdf/n3/reasoner.rb +57 -68
  91. data/lib/rdf/n3/refinements.rb +178 -0
  92. data/lib/rdf/n3/repository.rb +332 -0
  93. data/lib/rdf/n3/terminals.rb +80 -0
  94. data/lib/rdf/n3/vocab.rb +35 -7
  95. data/lib/rdf/n3/writer.rb +208 -148
  96. metadata +110 -52
  97. data/AUTHORS +0 -1
  98. data/History.markdown +0 -99
  99. data/lib/rdf/n3/algebra/log/equalTo.rb +0 -7
  100. data/lib/rdf/n3/algebra/log/notEqualTo.rb +0 -7
  101. data/lib/rdf/n3/algebra/log/notIncludes.rb +0 -12
  102. data/lib/rdf/n3/algebra/log/outputString.rb +0 -7
  103. data/lib/rdf/n3/algebra/math/absoluteValue.rb +0 -9
  104. data/lib/rdf/n3/algebra/math/equalTo.rb +0 -9
  105. data/lib/rdf/n3/algebra/math/greaterThan.rb +0 -9
  106. data/lib/rdf/n3/algebra/math/integerQuotient.rb +0 -9
  107. data/lib/rdf/n3/algebra/math/lessThan.rb +0 -9
  108. data/lib/rdf/n3/algebra/math/memberCount.rb +0 -9
  109. data/lib/rdf/n3/algebra/math/notEqualTo.rb +0 -9
  110. data/lib/rdf/n3/algebra/math/notGreaterThan.rb +0 -9
  111. data/lib/rdf/n3/algebra/math/notLessThan.rb +0 -9
  112. data/lib/rdf/n3/algebra/str/containsIgnoringCase.rb +0 -9
  113. data/lib/rdf/n3/algebra/str/endsWith.rb +0 -9
  114. data/lib/rdf/n3/algebra/str/equalIgnoringCase.rb +0 -9
  115. data/lib/rdf/n3/algebra/str/greaterThan.rb +0 -9
  116. data/lib/rdf/n3/algebra/str/lessThan.rb +0 -9
  117. data/lib/rdf/n3/algebra/str/notEqualIgnoringCase.rb +0 -9
  118. data/lib/rdf/n3/algebra/str/notGreaterThan.rb +0 -9
  119. data/lib/rdf/n3/algebra/str/notLessThan.rb +0 -9
  120. data/lib/rdf/n3/algebra/str/notMatches.rb +0 -9
  121. data/lib/rdf/n3/algebra/str/startsWith.rb +0 -56
  122. data/lib/rdf/n3/patches/array_hacks.rb +0 -53
  123. data/lib/rdf/n3/reader/meta.rb +0 -641
  124. data/lib/rdf/n3/reader/parser.rb +0 -239
@@ -0,0 +1,38 @@
1
+ module RDF::N3::Algebra::Math
2
+ ##
3
+ # The subject is an angle expressed in radians. The object is calulated as the tangent value of the subject.
4
+ class TanH < RDF::N3::Algebra::ResourceOperator
5
+ NAME = :mathTanH
6
+ URI = RDF::N3::Math.tanh
7
+
8
+ ##
9
+ # The math:tanh operator takes string or number and calculates its hyperbolic tangent. The inverse hyperbolic tangent of a concrete object can also calculate a variable subject.
10
+ #
11
+ # @param [RDF::Term] resource
12
+ # @param [:subject, :object] position
13
+ # @return [RDF::Term]
14
+ # @see RDF::N3::ResourceOperator#evaluate
15
+ def resolve(resource, position:)
16
+ case resource
17
+ when RDF::Query::Variable then resource
18
+ when RDF::Literal
19
+ case position
20
+ when :subject
21
+ as_literal(Math.tanh(resource.as_number.object))
22
+ when :object
23
+ as_literal(Math.atanh(resource.as_number.object))
24
+ end
25
+ else
26
+ nil
27
+ end
28
+ end
29
+
30
+ ##
31
+ # Input is either the subject or object
32
+ #
33
+ # @return [RDF::Term]
34
+ def input_operand
35
+ RDF::N3::List.new(values: operands)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,13 @@
1
+ require 'rdf'
2
+
3
+ module RDF::N3::Algebra
4
+ #
5
+ # A Notation3 Formula combines a graph with a BGP query.
6
+ class NotImplemented < SPARQL::Algebra::Operator
7
+ include RDF::N3::Algebra::Builtin
8
+
9
+ def initialize(*args, predicate:, **options)
10
+ raise NotImplementedError, "The #{predicate} operator is not implemented"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,123 @@
1
+ module RDF::N3::Algebra
2
+ ##
3
+ # This is a generic operator where the subject is a literal or binds to a literal and the object is either a constant that equals the evaluation of the subject, or a variable to which the result is bound in a solution
4
+ class ResourceOperator < SPARQL::Algebra::Operator::Binary
5
+ include SPARQL::Algebra::Query
6
+ include SPARQL::Algebra::Update
7
+ include RDF::N3::Algebra::Builtin
8
+
9
+ NAME = :resourceOperator
10
+
11
+ ##
12
+ # The operator takes a literal and provides a mechanism for subclasses to operate over (and validate) that argument.
13
+ #
14
+ # @param [RDF::Queryable] queryable
15
+ # the graph or repository to query
16
+ # @param [RDF::Query::Solutions] solutions
17
+ # solutions for chained queries
18
+ # @return [RDF::Query::Solutions]
19
+ def execute(queryable, solutions:, **options)
20
+ RDF::Query::Solutions(solutions.map do |solution|
21
+ subject = operand(0).evaluate(solution.bindings, formulae: formulae) || operand(0)
22
+ object = operand(1).evaluate(solution.bindings, formulae: formulae) || operand(1)
23
+ subject = formulae.fetch(subject, subject) if subject.node?
24
+ object = formulae.fetch(object, object) if object.node?
25
+
26
+ log_info(self.class.const_get(:NAME), "subject") {SXP::Generator.string(subject.to_sxp_bin).strip}
27
+ log_info(self.class.const_get(:NAME), "object") {SXP::Generator.string(object.to_sxp_bin).strip}
28
+ next unless valid?(subject, object)
29
+
30
+ lhs = resolve(subject, position: :subject)
31
+ if lhs.nil?
32
+ log_error(self.class.const_get(:NAME), "subject evaluates to null") {subject.inspect}
33
+ next
34
+ end
35
+
36
+ rhs = resolve(object, position: :object)
37
+ if rhs.nil?
38
+ log_error(self.class.const_get(:NAME), "object evaluates to null") {object.inspect}
39
+ next
40
+ end
41
+
42
+ if object.variable?
43
+ log_debug(self.class.const_get(:NAME), "result") {SXP::Generator.string(lhs.to_sxp_bin).strip}
44
+ solution.merge(object.to_sym => lhs)
45
+ elsif subject.variable?
46
+ log_debug(self.class.const_get(:NAME), "result") {SXP::Generator.string(rhs.to_sxp_bin).strip}
47
+ solution.merge(subject.to_sym => rhs)
48
+ elsif respond_to?(:apply)
49
+ res = apply(lhs, rhs)
50
+ log_debug(self.class.const_get(:NAME), "result") {SXP::Generator.string(res.to_sxp_bin).strip}
51
+ # Return the result applying subject and object
52
+ #require 'byebug'; byebug
53
+ case res
54
+ when RDF::Literal::TRUE
55
+ solution
56
+ when RDF::Literal::FALSE
57
+ nil
58
+ when RDF::Query::Solution
59
+ solution.merge(res)
60
+ else
61
+ log_error(self.class.const_get(:NAME), "unexpected result type")
62
+ nil
63
+ end
64
+ elsif rhs != lhs
65
+ log_debug(self.class.const_get(:NAME), "result: false")
66
+ nil
67
+ else
68
+ log_debug(self.class.const_get(:NAME), "result: true")
69
+ solution
70
+ end
71
+ end.compact.uniq)
72
+ end
73
+
74
+ ##
75
+ # Input is generically the subject
76
+ #
77
+ # @return [RDF::Term]
78
+ def input_operand
79
+ operand(0)
80
+ end
81
+
82
+ ##
83
+ # Subclasses implement `resolve`.
84
+ #
85
+ # Returns nil if resource does not validate, given its position
86
+ #
87
+ # @param [RDF::Term] resource
88
+ # @return [RDF::Term]
89
+ def resolve(resource, position: :subject)
90
+ raise NotImplemented
91
+ end
92
+
93
+ ##
94
+ # Subclasses may override or supplement validate to perform validation on the list subject
95
+ #
96
+ # @param [RDF::Term] subject
97
+ # @param [RDF::Term] object
98
+ # @return [Boolean]
99
+ def valid?(subject, object)
100
+ case subject
101
+ when RDF::Query::Variable
102
+ object.term?
103
+ when RDF::Term
104
+ object.term? || object.variable?
105
+ else
106
+ false
107
+ end
108
+ end
109
+
110
+ ##
111
+ # Returns a literal for the numeric argument.
112
+ def as_literal(object)
113
+ case object
114
+ when Float
115
+ literal = RDF::Literal(object, canonicalize: true)
116
+ literal.instance_variable_set(:@string, literal.to_s.downcase)
117
+ literal
118
+ else
119
+ RDF::Literal(object, canonicalize: true)
120
+ end
121
+ end
122
+ end
123
+ end
@@ -1,9 +1,27 @@
1
1
  module RDF::N3::Algebra::Str
2
2
  ##
3
3
  # The subject is a list of strings. The object is calculated as a concatenation of those strings.
4
- class Concatenation < SPARQL::Algebra::Operator::Binary
5
- include RDF::Util::Logger
6
-
4
+ #
5
+ # @example
6
+ # ("a" "b") string:concatenation :s
7
+ class Concatenation < RDF::N3::Algebra::ListOperator
7
8
  NAME = :strConcatenation
9
+ URI = RDF::N3::Str.concatenation
10
+
11
+ ##
12
+ # The string:concatenation operator takes a list of terms cast to strings and either binds the result of concatenating them to the output variable, removes a solution that does equal the literal object.
13
+ #
14
+ # List entries are stringified using {SPARQL::Algebra::Expression.cast}.
15
+ #
16
+ # @param [RDF::N3::List] list
17
+ # @return [RDF::Term]
18
+ # @see RDF::N3::ListOperator#evaluate
19
+ def resolve(list)
20
+ RDF::Literal(
21
+ list.to_a.map do |o|
22
+ SPARQL::Algebra::Expression.cast(RDF::XSD.string, o)
23
+ end.join("")
24
+ )
25
+ end
8
26
  end
9
27
  end
@@ -1,9 +1,33 @@
1
1
  module RDF::N3::Algebra::Str
2
- ##
3
2
  # True iff the subject string contains the object string.
4
- class Contains < SPARQL::Algebra::Operator::Binary
5
- include RDF::Util::Logger
6
-
3
+ class Contains < RDF::N3::Algebra::ResourceOperator
7
4
  NAME = :strContains
5
+ URI = RDF::N3::Str.contains
6
+
7
+ ##
8
+ # Resolves inputs as strings.
9
+ #
10
+ # @param [RDF::Term] resource
11
+ # @param [:subject, :object] position
12
+ # @return [RDF::Literal]
13
+ # @see RDF::N3::ResourceOperator#evaluate
14
+ def resolve(resource, position:)
15
+ resource if resource.term?
16
+ end
17
+
18
+ # Neither subect nor object are considered inputs, and must be resolved before evaluation.
19
+ def input_operand
20
+ RDF::N3::List.new
21
+ end
22
+
23
+ ##
24
+ # @param [String] left
25
+ # a literal
26
+ # @param [String] right
27
+ # a literal
28
+ # @return [RDF::Literal::Boolean]
29
+ def apply(left, right)
30
+ RDF::Literal(left.to_s.include?(right.to_s))
31
+ end
8
32
  end
9
33
  end
@@ -0,0 +1,33 @@
1
+ module RDF::N3::Algebra::Str
2
+ # True iff the subject string contains the object string, with the comparison done ignoring the difference between upper case and lower case characters.
3
+ class ContainsIgnoringCase < RDF::N3::Algebra::ResourceOperator
4
+ NAME = :strContainsIgnoringCase
5
+ URI = RDF::N3::Str.containsIgnoringCase
6
+
7
+ ##
8
+ # Resolves inputs as lower-case strings.
9
+ #
10
+ # @param [RDF::Term] resource
11
+ # @param [:subject, :object] position
12
+ # @return [RDF::Literal]
13
+ # @see RDF::N3::ResourceOperator#evaluate
14
+ def resolve(resource, position:)
15
+ RDF::Literal(resource.to_s.downcase) if resource.term?
16
+ end
17
+
18
+ # Both subject and object are inputs.
19
+ def input_operand
20
+ RDF::N3::List.new(values: operands)
21
+ end
22
+
23
+ ##
24
+ # @param [String] left
25
+ # a literal
26
+ # @param [String] right
27
+ # a literal
28
+ # @return [RDF::Literal::Boolean]
29
+ def apply(left, right)
30
+ RDF::Literal(left.to_s.include?(right.to_s))
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ module RDF::N3::Algebra::Str
2
+ # True iff the subject string ends with the object string.
3
+ class EndsWith < RDF::N3::Algebra::ResourceOperator
4
+ NAME = :strEndsWith
5
+ URI = RDF::N3::Str.endsWith
6
+
7
+ ##
8
+ # Resolves inputs as strings.
9
+ #
10
+ # @param [RDF::Term] resource
11
+ # @param [:subject, :object] position
12
+ # @return [RDF::Literal]
13
+ # @see RDF::N3::ResourceOperator#evaluate
14
+ def resolve(resource, position:)
15
+ resource if resource.term?
16
+ end
17
+
18
+ # Both subject and object are inputs.
19
+ def input_operand
20
+ RDF::N3::List.new(values: operands)
21
+ end
22
+
23
+ ##
24
+ # @param [RDF::Literal] left
25
+ # a literal
26
+ # @param [RDF::Literal] right
27
+ # a literal
28
+ # @return [RDF::Literal::Boolean]
29
+ def apply(left, right)
30
+ RDF::Literal(left.to_s.end_with?(right.to_s))
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ module RDF::N3::Algebra::Str
2
+ class EqualIgnoringCase < RDF::N3::Algebra::ResourceOperator
3
+ NAME = :strEqualIgnoringCase
4
+ URI = RDF::N3::Str.equalIgnoringCase
5
+
6
+ ##
7
+ # Resolves inputs as lower-case strings.
8
+ #
9
+ # @param [RDF::Term] resource
10
+ # @param [:subject, :object] position
11
+ # @return [RDF::Literal]
12
+ # @see RDF::N3::ResourceOperator#evaluate
13
+ def resolve(resource, position:)
14
+ RDF::Literal(resource.to_s.downcase) if resource.term?
15
+ end
16
+
17
+ # Both subject and object are inputs.
18
+ def input_operand
19
+ RDF::N3::List.new(values: operands)
20
+ end
21
+
22
+ ##
23
+ # True iff the subject string is the same as object string ignoring differences between upper and lower case.
24
+ #
25
+ # @param [RDF::Literal] left
26
+ # a literal
27
+ # @param [RDF::Literal] right
28
+ # a literal
29
+ # @return [RDF::Literal::Boolean]
30
+ def apply(left, right)
31
+ RDF::Literal(left.to_s == right.to_s)
32
+ end
33
+ end
34
+ end
@@ -1,9 +1,17 @@
1
1
  module RDF::N3::Algebra::Str
2
- ##
3
2
  # The subject is a list, whose first member is a format string, and whose remaining members are arguments to the format string. The formating string is in the style of python's % operator, very similar to C's sprintf(). The object is calculated from the subject.
4
- class Format < SPARQL::Algebra::Operator::Binary
5
- include RDF::Util::Logger
6
-
3
+ class Format < RDF::N3::Algebra::ListOperator
4
+ include RDF::N3::Algebra::Builtin
7
5
  NAME = :strFormat
6
+ URI = RDF::N3::Str.format
7
+
8
+ ##
9
+ # @param [RDF::N3::List] list
10
+ # @return [RDF::Term]
11
+ # @see RDF::N3::ListOperator#evaluate
12
+ def resolve(list)
13
+ format, *args = list.to_a.map(&:value)
14
+ str = RDF::Literal(format % args)
15
+ end
8
16
  end
9
17
  end
@@ -0,0 +1,38 @@
1
+ module RDF::N3::Algebra::Str
2
+ # True iff the string is greater than the object when ordered according to Unicode(tm) code order.
3
+ class GreaterThan < RDF::N3::Algebra::ResourceOperator
4
+ NAME = :strGreaterThan
5
+ URI = RDF::N3::Str.greaterThan
6
+
7
+ ##
8
+ # The string:greaterThan compares subject with object as strings.
9
+ #
10
+ # @param [RDF::Term] resource
11
+ # @param [:subject, :object] position
12
+ # @return [RDF::Term]
13
+ # @see RDF::N3::ResourceOperator#evaluate
14
+ def resolve(resource, position:)
15
+ resource if resource.literal?
16
+ end
17
+
18
+ # Both subject and object are inputs.
19
+ def input_operand
20
+ RDF::N3::List.new(values: operands)
21
+ end
22
+
23
+ ##
24
+ # @param [RDF::Literal] left
25
+ # a literal
26
+ # @param [RDF::Literal] right
27
+ # a literal
28
+ # @return [RDF::Literal::Boolean]
29
+ def apply(left, right)
30
+ case
31
+ when !left.is_a?(RDF::Term) || !right.is_a?(RDF::Term) || !left.compatible?(right)
32
+ log_error(NAME) {"expected two RDF::Literal operands, but got #{left.inspect} and #{right.inspect}"}
33
+ when left > right then RDF::Literal::TRUE
34
+ else RDF::Literal::FALSE
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,33 @@
1
+ module RDF::N3::Algebra::Str
2
+ # True iff the string is less than the object when ordered according to Unicode(tm) code order.
3
+ class LessThan < RDF::N3::Algebra::ResourceOperator
4
+ NAME = :strLessThan
5
+ URI = RDF::N3::Str.lessThan
6
+
7
+ ##
8
+ # Resolves inputs as strings.
9
+ #
10
+ # @param [RDF::Term] resource
11
+ # @param [:subject, :object] position
12
+ # @return [RDF::Literal]
13
+ # @see RDF::N3::ResourceOperator#evaluate
14
+ def resolve(resource, position:)
15
+ resource if resource.term?
16
+ end
17
+
18
+ # Both subject and object are inputs.
19
+ def input_operand
20
+ RDF::N3::List.new(values: operands)
21
+ end
22
+
23
+ ##
24
+ # @param [RDF::Literal] left
25
+ # a literal
26
+ # @param [RDF::Literal] right
27
+ # a literal
28
+ # @return [RDF::Literal::Boolean]
29
+ def apply(left, right)
30
+ RDF::Literal(left.to_s < right.to_s)
31
+ end
32
+ end
33
+ end