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
@@ -1,9 +1,37 @@
1
1
  module RDF::N3::Algebra::Str
2
- ##
3
- # The subject is a string; the object is is a regular expression in the perl, python style. It is true iff the string matches the regexp.
4
- class Matches < SPARQL::Algebra::Operator::Binary
5
- include RDF::Util::Logger
6
-
2
+ # The subject is a string; the object is is a regular expression in the perl, python style.
3
+ # It is true iff the string matches the regexp.
4
+ class Matches < RDF::N3::Algebra::ResourceOperator
7
5
  NAME = :strMatches
6
+ URI = RDF::N3::Str.matches
7
+
8
+ ##
9
+ # Resolves inputs as strings.
10
+ #
11
+ # @param [RDF::Term] resource
12
+ # @param [:subject, :object] position
13
+ # @return [RDF::Literal]
14
+ # @see RDF::N3::ResourceOperator#evaluate
15
+ def resolve(resource, position:)
16
+ resource if resource.literal?
17
+ end
18
+
19
+ # Neither subect nor object are considered inputs, and must be resolved before evaluation.
20
+ def input_operand
21
+ RDF::N3::List.new
22
+ end
23
+
24
+ ##
25
+ # Tre if right, treated as a regular expression, matches left
26
+ #
27
+ # @param [RDF::Literal] left
28
+ # a simple literal
29
+ # @param [RDF::Literal] right
30
+ # a simple literal
31
+ # @return [RDF::Literal::Boolean] `true` or `false`
32
+ # @see https://www.w3.org/TR/xpath-functions/#regex-syntax
33
+ def apply(left, right)
34
+ RDF::Literal(Regexp.new(right.to_s).match?(left.to_s))
35
+ end
8
36
  end
9
37
  end
@@ -0,0 +1,17 @@
1
+ module RDF::N3::Algebra::Str
2
+ # True iff the subject string is the NOT same as object string ignoring differences between upper and lower case.
3
+ class NotEqualIgnoringCase < EqualIgnoringCase
4
+ NAME = :strNotEqualIgnoringCase
5
+ URI = RDF::N3::Str.notEqualIgnoringCase
6
+
7
+ ##
8
+ # @param [RDF::Literal] left
9
+ # a literal
10
+ # @param [RDF::Literal] right
11
+ # a literal
12
+ # @return [RDF::Literal::Boolean]
13
+ def apply(left, right)
14
+ RDF::Literal(super != RDF::Literal::TRUE)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module RDF::N3::Algebra::Str
2
+ # True iff the string is NOT greater than the object when ordered according to Unicode(tm) code order.
3
+ class NotGreaterThan < GreaterThan
4
+ NAME = :strNotGreaterThan
5
+ URI = RDF::N3::Str.notGreaterThan
6
+
7
+ ##
8
+ # @param [RDF::Literal] left
9
+ # a literal
10
+ # @param [RDF::Literal] right
11
+ # a literal
12
+ # @return [RDF::Literal::Boolean]
13
+ def apply(left, right)
14
+ RDF::Literal(super != RDF::Literal::TRUE)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module RDF::N3::Algebra::Str
2
+ # True iff the string is NOT less than the object when ordered according to Unicode(tm) code order.
3
+ class NotLessThan < LessThan
4
+ NAME = :strNotLessThan
5
+ URI = RDF::N3::Str.notLessThan
6
+
7
+ ##
8
+ # @param [RDF::Literal] left
9
+ # a literal
10
+ # @param [RDF::Literal] right
11
+ # a literal
12
+ # @return [RDF::Literal::Boolean]
13
+ def apply(left, right)
14
+ RDF::Literal(super != RDF::Literal::TRUE)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ module RDF::N3::Algebra::Str
2
+ # The subject string; the object is a regular expression in the perl, python style. It is true iff the string does NOT match the regexp.
3
+ class NotMatches < Matches
4
+ NAME = :strNotMatches
5
+ URI = RDF::N3::Str.notMatches
6
+
7
+ ##
8
+ # @param [RDF::Literal] text
9
+ # a simple literal
10
+ # @param [RDF::Literal] pattern
11
+ # a simple literal
12
+ # @return [RDF::Literal::Boolean] `true` or `false`
13
+ # @see https://www.w3.org/TR/xpath-functions/#regex-syntax
14
+ def apply(text, pattern)
15
+ RDF::Literal(super != RDF::Literal::TRUE)
16
+ end
17
+ end
18
+ end
@@ -1,12 +1,35 @@
1
1
  module RDF::N3::Algebra::Str
2
- ##
3
- # A built-in for replacing characters or sub. takes a list of 3 strings; the first is the input data, the second the old and the third the new string. The object is calculated as the rplaced string.
2
+ # A built-in for replacing characters or sub. takes a list of 3 strings; the first is the input data, the second the old and the third the new string. The object is calculated as the replaced string.
4
3
  #
5
4
  # @example
6
5
  # ("fofof bar", "of", "baz") string:replace "fbazbaz bar"
7
- class Replace < SPARQL::Algebra::Operator::Binary
8
- include RDF::Util::Logger
9
-
6
+ class Replace < RDF::N3::Algebra::ListOperator
7
+ include RDF::N3::Algebra::Builtin
10
8
  NAME = :strReplace
9
+ URI = RDF::N3::Str.replace
10
+
11
+ ##
12
+ # @param [RDF::N3::List] list
13
+ # @return [RDF::Term]
14
+ # @see RDF::N3::ListOperator#evaluate
15
+ def resolve(list)
16
+ format, *args = list.to_a.map(&:value)
17
+ input, old_str, new_str = list.to_a
18
+ RDF::Literal(input.to_s.gsub(old_str.to_s, new_str.to_s))
19
+ end
20
+
21
+ ##
22
+ # Subclasses may override or supplement validate to perform validation on the list subject
23
+ #
24
+ # @param [RDF::N3::List] list
25
+ # @return [Boolean]
26
+ def validate(list)
27
+ if super && list.length == 3 && list.to_a.all?(&:literal?)
28
+ true
29
+ else
30
+ log_error(NAME) {"list must have exactly three entries: #{list.to_sxp}"}
31
+ false
32
+ end
33
+ end
11
34
  end
12
35
  end
@@ -1,9 +1,35 @@
1
1
  module RDF::N3::Algebra::Str
2
- ##
3
- # The subject is a list of two strings. The second string is a regular expression in the perl, python style. It must contain one group (a part in parentheses). If the first string in the list matches the regular expression, then the object is calculated as being thepart of the first string which matches the group.
4
- class Scrape < SPARQL::Algebra::Operator::Binary
5
- include RDF::Util::Logger
6
-
2
+ # The subject is a list of two strings. The second string is a regular expression in the perl, python style. It must contain one group (a part in parentheses). If the first string in the list matches the regular expression, then the object is calculated as being the part of the first string which matches the group.
3
+ #
4
+ # @example
5
+ # ("abcdef" "ab(..)ef") string:scrape "cd"
6
+ class Scrape < RDF::N3::Algebra::ListOperator
7
+ include RDF::N3::Algebra::Builtin
7
8
  NAME = :strScrape
9
+ URI = RDF::N3::Str.scrape
10
+
11
+ ##
12
+ # @param [RDF::N3::List] list
13
+ # @return [RDF::Term]
14
+ # @see RDF::N3::ListOperator#evaluate
15
+ def resolve(list)
16
+ input, regex = list.to_a
17
+ md = Regexp.new(regex.to_s).match(input.to_s)
18
+ RDF::Literal(md[1]) if md
19
+ end
20
+
21
+ ##
22
+ # Subclasses may override or supplement validate to perform validation on the list subject
23
+ #
24
+ # @param [RDF::N3::List] list
25
+ # @return [Boolean]
26
+ def validate(list)
27
+ if super && list.length == 2
28
+ true
29
+ else
30
+ log_error(NAME) {"list must have exactly two entries: #{list.to_sxp}"}
31
+ false
32
+ end
33
+ end
8
34
  end
9
35
  end
@@ -0,0 +1,33 @@
1
+ module RDF::N3::Algebra::Str
2
+ # True iff the subject string starts with the object string.
3
+ class StartsWith < RDF::N3::Algebra::ResourceOperator
4
+ NAME = :strStartsWith
5
+ URI = RDF::N3::Str.startsWith
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.start_with?(right.to_s))
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,35 @@
1
+ module RDF::N3::Algebra::Time
2
+ ##
3
+ # For a date-time, its time:day is the day of the month.
4
+ #
5
+ # @see https://www.w3.org/TR/xpath-functions/#func-day-from-dateTime
6
+ class Day < RDF::N3::Algebra::ResourceOperator
7
+ NAME = :timeDay
8
+ URI = RDF::N3::Time.day
9
+
10
+ ##
11
+ # The time:day operator takes string or dateTime and extracts the day component.
12
+ #
13
+ # @param [RDF::Term] resource
14
+ # @param [:subject, :object] position
15
+ # @return [RDF::Term]
16
+ # @see RDF::N3::ResourceOperator#evaluate
17
+ def resolve(resource, position:)
18
+ case position
19
+ when :subject
20
+ return nil unless resource.literal?
21
+ resource = resource.as_datetime
22
+ RDF::Literal(resource.object.strftime("%d").to_i)
23
+ when :object
24
+ return nil unless resource.literal? || resource.variable?
25
+ resource
26
+ end
27
+ end
28
+
29
+ ##
30
+ # There is no day unless it was specified in the lexical form
31
+ def valid?(subject, object)
32
+ subject.value.match?(%r(^\d{4}-\d{2}-\d{2}))
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,27 @@
1
+ module RDF::N3::Algebra::Time
2
+ ##
3
+ # For a date-time, its time:dayOfWeek is the the day number within the week, Sunday being 0.
4
+ class DayOfWeek < RDF::N3::Algebra::ResourceOperator
5
+ NAME = :timeDayOfWeek
6
+ URI = RDF::N3::Time.dayOfWeek
7
+
8
+ ##
9
+ # The time:dayOfWeek operator takes string or dateTime and returns the 0-based day of the week.
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 position
17
+ when :subject
18
+ return nil unless resource.literal?
19
+ resource = resource.as_datetime
20
+ RDF::Literal(resource.object.strftime("%w").to_i)
21
+ when :object
22
+ return nil unless resource.literal? || resource.variable?
23
+ resource
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,29 @@
1
+ module RDF::N3::Algebra::Time
2
+ ##
3
+ # For a date-time format string, its time:gmtime is the result of formatting the Universal Time of processing in the format given. If the format string has zero length, then the ISOdate standard format is used. `[ is time:gmtime of ""]` the therefore the current date time. It will end with "Z" as a timezone code.
4
+ #
5
+ # @see https://www.w3.org/TR/xpath-functions/#func-current-dateTime
6
+ class GmTime < RDF::N3::Algebra::ResourceOperator
7
+ NAME = :timeGmTime
8
+ URI = RDF::N3::Time.gmTime
9
+
10
+ ##
11
+ # The time:gmTime operator takes string or dateTime and returns current time formatted according to the subject.
12
+ #
13
+ # @param [RDF::Term] resource
14
+ # @param [:subject, :object] position
15
+ # @return [RDF::Term]
16
+ # @see RDF::N3::ResourceOperator#evaluate
17
+ def resolve(resource, position:)
18
+ case position
19
+ when :subject
20
+ return nil unless resource.literal?
21
+ resource = "%FT%T%:z" if resource.to_s.empty?
22
+ RDF::Literal(DateTime.now.new_offset(0).strftime(resource.to_s))
23
+ when :object
24
+ return nil unless resource.literal? || resource.variable?
25
+ resource
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,35 @@
1
+ module RDF::N3::Algebra::Time
2
+ ##
3
+ # For a date-time, its time:hour is the hour in the 24 hour clock.
4
+ #
5
+ # @see https://www.w3.org/TR/xpath-functions/#func-hours-from-dateTime
6
+ class Hour < RDF::N3::Algebra::ResourceOperator
7
+ NAME = :timeHour
8
+ URI = RDF::N3::Time.hour
9
+
10
+ ##
11
+ # The time:hour operator takes string or dateTime and extracts the hour component.
12
+ #
13
+ # @param [RDF::Term] resource
14
+ # @param [:subject, :object] position
15
+ # @return [RDF::Term]
16
+ # @see RDF::N3::ResourceOperator#evaluate
17
+ def resolve(resource, position:)
18
+ case position
19
+ when :subject
20
+ return nil unless resource.literal?
21
+ resource = resource.as_datetime
22
+ RDF::Literal(resource.object.strftime("%H").to_i)
23
+ when :object
24
+ return nil unless resource.literal? || resource.variable?
25
+ resource
26
+ end
27
+ end
28
+
29
+ ##
30
+ # There is no hour unless it was specified in the lexical form
31
+ def valid?(subject, object)
32
+ subject.value.match?(%r(^\d{4}-\d{2}-\d{2}T\d{2}))
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,59 @@
1
+ module RDF::N3::Algebra::Time
2
+ ##
3
+ # Iff the _subject_ is a `xsd:dateTime` and the _object_ is the integer number of seconds since the beginning of the era on a given system. Don't assume a particular value, always test for it. The _object_ can be calculated as a function of the _subject_.
4
+ #
5
+ # @see https://www.w3.org/TR/xpath-functions/#func-timezone-from-dateTime
6
+ class InSeconds < RDF::N3::Algebra::ResourceOperator
7
+ NAME = :timeInSeconds
8
+ URI = RDF::N3::Time.inSeconds
9
+
10
+ ##
11
+ # The time:inseconds operator takes may have either a bound subject or object.
12
+ #
13
+ # @param [RDF::Term] resource
14
+ # @param [:subject, :object] position
15
+ # @return [RDF::Term]
16
+ # @see RDF::N3::ResourceOperator#evaluate
17
+ def resolve(resource, position:)
18
+ case position
19
+ when :subject
20
+ case resource
21
+ when RDF::Query::Variable
22
+ resource
23
+ when RDF::Literal
24
+ resource = resource.as_datetime
25
+ # Subject evaluates to seconds from the epoc
26
+ RDF::Literal::Integer.new(resource.object.strftime("%s"))
27
+ else
28
+ nil
29
+ end
30
+ when :object
31
+ case resource
32
+ when RDF::Query::Variable
33
+ resource
34
+ when RDF::Literal
35
+ resource = resource.as_number
36
+ # Object evaluates to the DateTime representation of the seconds form the epoc
37
+ RDF::Literal(RDF::Literal::DateTime.new(::Time.at(resource).utc.to_datetime).to_s)
38
+ else
39
+ nil
40
+ end
41
+ end
42
+ end
43
+
44
+ # Either subject or object must be a bound resource
45
+ def valid?(subject, object)
46
+ return true if subject.literal? || object.literal?
47
+ log_error(NAME) {"subject or object are not literals: #{subject.inspect}, #{object.inspect}"}
48
+ false
49
+ end
50
+
51
+ ##
52
+ # Return both subject and object operands.
53
+ #
54
+ # @return [RDF::Term]
55
+ def input_operand
56
+ RDF::N3::List.new(values: operands)
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,29 @@
1
+ module RDF::N3::Algebra::Time
2
+ ##
3
+ # For a date-time format string, its time:localTime is the result of formatting the current time of processing and local timezone in the format given. If the format string has zero length, then the ISOdate standrad format is used. [ is time:localTime of ""] the therefore the current date time. It will end with a numeric timezone code or "Z" for UTC (GMT).
4
+ #
5
+ # @see https://www.w3.org/TR/xpath-functions/#func-current-dateTime
6
+ class LocalTime < RDF::N3::Algebra::ResourceOperator
7
+ NAME = :timeLocalTime
8
+ URI = RDF::N3::Time.localTime
9
+
10
+ ##
11
+ # The time:localTime operator takes string or dateTime and returns current time formatted according to the subject.
12
+ #
13
+ # @param [RDF::Term] resource
14
+ # @param [:subject, :object] position
15
+ # @return [RDF::Term]
16
+ # @see RDF::N3::ResourceOperator#evaluate
17
+ def resolve(resource, position:)
18
+ case position
19
+ when :subject
20
+ return nil unless resource.literal?
21
+ resource = "%FT%T%:z" if resource.to_s.empty?
22
+ RDF::Literal(DateTime.now.strftime(resource.to_s))
23
+ when :object
24
+ return nil unless resource.literal? || resource.variable?
25
+ resource
26
+ end
27
+ end
28
+ end
29
+ end