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,13 +1,42 @@
1
1
  module RDF::N3::Algebra::List
2
2
  ##
3
- # Iff the subject is a list of lists and the concatenation of all those lists is the object, then this is true.
3
+ # Iff the subject is a list of lists and the concatenation of all those lists is the object, then this is true. The object can be calculated as a function of the subject.
4
+ #
4
5
  # @example
5
6
  # ( (1 2) (3 4) ) list:append (1 2 3 4).
6
7
  #
7
8
  # The object can be calculated as a function of the subject.
8
- class Append < SPARQL::Algebra::Operator::Binary
9
- include RDF::Util::Logger
10
-
9
+ class Append < RDF::N3::Algebra::ListOperator
11
10
  NAME = :listAppend
11
+ URI = RDF::N3::List.append
12
+
13
+ ##
14
+ # Resolves this operator using the given variable `bindings`.
15
+ # If the last operand is a variable, it creates a solution for each element in the list.
16
+ #
17
+ # @param [RDF::N3::List] list
18
+ # @return [RDF::Term]
19
+ # @see RDF::N3::ListOperator#evaluate
20
+ def resolve(list)
21
+ flattened = list.to_a.map(&:to_a).flatten
22
+ # Bind a new list based on the values, whos subject use made up from original list subjects
23
+ subj = RDF::Node.intern(list.map(&:subject).hash)
24
+ RDF::N3::List.new(subject: subj, values: flattened)
25
+ end
26
+
27
+ ##
28
+ # The list argument must be a pair of literals.
29
+ #
30
+ # @param [RDF::N3::List] list
31
+ # @return [Boolean]
32
+ # @see RDF::N3::ListOperator#validate
33
+ def validate(list)
34
+ if super && list.to_a.all? {|li| li.list?}
35
+ true
36
+ else
37
+ log_error(NAME) {"operand is not a list of lists: #{list.to_sxp}"}
38
+ false
39
+ end
40
+ end
12
41
  end
13
42
  end
@@ -0,0 +1,24 @@
1
+ module RDF::N3::Algebra::List
2
+ ##
3
+ # Iff the subject is a list and the object is the first thing that list, then this is true. The object can be calculated as a function of the list.
4
+ #
5
+ # @example
6
+ # { ( 1 2 3 4 5 6 ) list:first 1 } => { :test1 a :SUCCESS }.
7
+ #
8
+ # The object can be calculated as a function of the list.
9
+ class First < RDF::N3::Algebra::ListOperator
10
+ NAME = :listFirst
11
+ URI = RDF::N3::List.first
12
+
13
+ ##
14
+ # Resolves this operator using the given variable `bindings`.
15
+ # If the last operand is a variable, it creates a solution for each element in the list.
16
+ #
17
+ # @param [RDF::N3::List] list
18
+ # @return [RDF::Term]
19
+ # @see RDF::N3::ListOperator#evaluate
20
+ def resolve(list)
21
+ list.first
22
+ end
23
+ end
24
+ end
@@ -1,9 +1,48 @@
1
1
  module RDF::N3::Algebra::List
2
2
  ##
3
3
  # Iff the object is a list and the subject is in that list, then this is true.
4
- class In < SPARQL::Algebra::Operator::Binary
5
- include RDF::Util::Logger
6
-
4
+ #
5
+ # @example
6
+ # { 1 list:in ( 1 2 3 4 5 ) } => { :test4a a :SUCCESS }.
7
+ class In < RDF::N3::Algebra::ListOperator
7
8
  NAME = :listIn
9
+ URI = RDF::N3::List.in
10
+
11
+ ##
12
+ # Evaluates this operator using the given variable `bindings`.
13
+ # If the first operand is a variable, it creates a solution for each element in the list.
14
+ #
15
+ # @param [RDF::Queryable] queryable
16
+ # the graph or repository to query
17
+ # @param [RDF::Query::Solutions] solutions
18
+ # solutions for chained queries
19
+ # @return [RDF::Query::Solutions]
20
+ def execute(queryable, solutions:, **options)
21
+ RDF::Query::Solutions(solutions.map do |solution|
22
+ subject = operand(0).evaluate(solution.bindings, formulae: formulae) || operand(0)
23
+ # Might be a variable or node evaluating to a list in queryable, or might be a list with variables
24
+ list = operand(1).evaluate(solution.bindings, formulae: formulae)
25
+ next unless list
26
+ # If it evaluated to a BNode, re-expand as a list
27
+ list = RDF::N3::List.try_list(list, queryable).evaluate(solution.bindings, formulae: formulae)
28
+
29
+ log_debug(NAME) {"subject: #{subject.to_sxp}, list: #{list.to_sxp}"}
30
+ unless list.list? && list.valid?
31
+ log_error(NAME) {"operand is not a list: #{list.to_sxp}"}
32
+ next
33
+ end
34
+
35
+ if subject.variable?
36
+ # Bind all list entries to this solution, creates an array of solutions
37
+ list.to_a.map do |term|
38
+ solution.merge(subject.to_sym => term)
39
+ end
40
+ elsif list.to_a.include?(subject)
41
+ solution
42
+ else
43
+ nil
44
+ end
45
+ end.flatten.compact.uniq)
46
+ end
8
47
  end
9
48
  end
@@ -1,11 +1,24 @@
1
1
  module RDF::N3::Algebra::List
2
2
  ##
3
- # Iff the suject is a list and the obbject is the last thing that list, then this is true.
3
+ # Iff the subject is a list and the object is the last thing that list, then this is true. The object can be calculated as a function of the list.
4
+ #
5
+ # @example
6
+ # { ( 1 2 3 4 5 6 ) list:last 6 } => { :test1 a :SUCCESS }.
4
7
  #
5
8
  # The object can be calculated as a function of the list.
6
- class Last < SPARQL::Algebra::Operator::Binary
7
- include RDF::Util::Logger
8
-
9
+ class Last < RDF::N3::Algebra::ListOperator
9
10
  NAME = :listLast
11
+ URI = RDF::N3::List.last
12
+
13
+ ##
14
+ # Resolves this operator using the given variable `bindings`.
15
+ # If the last operand is a variable, it creates a solution for each element in the list.
16
+ #
17
+ # @param [RDF::N3::List] list
18
+ # @return [RDF::Term]
19
+ # @see RDF::N3::ListOperator#evaluate
20
+ def resolve(list)
21
+ list.last
22
+ end
10
23
  end
11
24
  end
@@ -0,0 +1,24 @@
1
+ module RDF::N3::Algebra::List
2
+ ##
3
+ # Iff the subject is a list and the object is the last thing that list, then this is true. The object can be calculated as a function of the list.
4
+ #
5
+ # @example
6
+ # { ( 1 2 3 4 5 6 ) list:length 6 } => { :test1 a :SUCCESS }.
7
+ #
8
+ # The object can be calculated as a function of the list.
9
+ class Length < RDF::N3::Algebra::ListOperator
10
+ NAME = :listLength
11
+ URI = RDF::N3::List.length
12
+
13
+ ##
14
+ # Resolves this operator using the given variable `bindings`.
15
+ # If the last operand is a variable, it creates a solution for each element in the list.
16
+ #
17
+ # @param [RDF::N3::List] list
18
+ # @return [RDF::Term]
19
+ # @see RDF::N3::ListOperator#evaluate
20
+ def resolve(list)
21
+ RDF::Literal(list.length)
22
+ end
23
+ end
24
+ end
@@ -1,7 +1,44 @@
1
1
  module RDF::N3::Algebra::List
2
2
  ##
3
- # Iff the subject is a list and the obbject is in that list, then this is true.
4
- class Member < SPARQL::Algebra::Operator::Binary
3
+ # Iff the subject is a list and the object is in that list, then this is true.
4
+ class Member < RDF::N3::Algebra::ListOperator
5
5
  NAME = :listMember
6
+ URI = RDF::N3::List.member
7
+
8
+ ##
9
+ # Evaluates this operator using the given variable `bindings`.
10
+ # If the last operand is a variable, it creates a solution for each element in the list.
11
+ #
12
+ # @param [RDF::Queryable] queryable
13
+ # the graph or repository to query
14
+ # @param [RDF::Query::Solutions] solutions
15
+ # solutions for chained queries
16
+ # @return [RDF::Query::Solutions]
17
+ def execute(queryable, solutions:, **options)
18
+ RDF::Query::Solutions(solutions.map do |solution|
19
+ list = operand(0).evaluate(solution.bindings, formulae: formulae)
20
+ next unless list
21
+ list = RDF::N3::List.try_list(list, queryable).evaluate(solution.bindings, formulae: formulae)
22
+ object = operand(1).evaluate(solution.bindings, formulae: formulae) || operand(1)
23
+ object = formulae[object].deep_dup if object.node? && formulae.has_key?(object)
24
+
25
+ log_debug(NAME) {"list: #{list.to_sxp}, object: #{object.to_sxp}"}
26
+ unless list.list? && list.valid?
27
+ log_error(NAME) {"operand is not a list: #{list.to_sxp}"}
28
+ next
29
+ end
30
+
31
+ if object.variable?
32
+ # Bind all list entries to this solution, creates an array of solutions
33
+ list.to_a.map do |term|
34
+ solution.merge(object.to_sym => term)
35
+ end
36
+ elsif list.to_a.include?(object)
37
+ solution
38
+ else
39
+ nil
40
+ end
41
+ end.flatten.compact.uniq)
42
+ end
6
43
  end
7
44
  end
@@ -0,0 +1,83 @@
1
+ module RDF::N3::Algebra
2
+ ##
3
+ # This is a generic operator where the subject is a list or binds to a list 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 ListOperator < SPARQL::Algebra::Operator::Binary
5
+ include SPARQL::Algebra::Query
6
+ include SPARQL::Algebra::Update
7
+ include RDF::N3::Algebra::Builtin
8
+
9
+ NAME = :listOperator
10
+
11
+ ##
12
+ # The operator takes a list and provides a mechanism for subclasses to operate over (and validate) that list 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
+ # Might be a variable or node evaluating to a list in queryable, or might be a list with variables
22
+ subject = operand(0).evaluate(solution.bindings, formulae: formulae)
23
+ next unless subject
24
+ # If it evaluated to a BNode, re-expand as a list
25
+ subject = RDF::N3::List.try_list(subject, queryable).evaluate(solution.bindings, formulae: formulae)
26
+ object = operand(1).evaluate(solution.bindings, formulae: formulae) || operand(1)
27
+ object = formulae.fetch(object, object) if object.node?
28
+
29
+ log_info(self.class.const_get(:NAME), "subject") {SXP::Generator.string(subject.to_sxp_bin).strip}
30
+ log_info(self.class.const_get(:NAME), "object") {SXP::Generator.string(object.to_sxp_bin).strip}
31
+ next unless validate(subject)
32
+
33
+ lhs = resolve(subject)
34
+ if lhs.nil?
35
+ log_error(self.class.const_get(:NAME), "subject evaluates to null") {subject.inspect}
36
+ next
37
+ end
38
+
39
+ if object.variable?
40
+ log_debug(self.class.const_get(:NAME), "result") {SXP::Generator.string(lhs.to_sxp_bin).strip}
41
+ solution.merge(object.to_sym => lhs)
42
+ elsif object != lhs
43
+ log_debug(self.class.const_get(:NAME), "result: false")
44
+ nil
45
+ else
46
+ log_debug(self.class.const_get(:NAME), "result: true")
47
+ solution
48
+ end
49
+ end.compact.uniq)
50
+ end
51
+
52
+ ##
53
+ # Input is generically the subject
54
+ #
55
+ # @return [RDF::Term]
56
+ def input_operand
57
+ operand(0)
58
+ end
59
+
60
+ ##
61
+ # Subclasses implement `resolve`.
62
+ #
63
+ # @param [RDF::N3::List] list
64
+ # @return [RDF::Term]
65
+ def resolve(list)
66
+ raise NotImplemented
67
+ end
68
+
69
+ ##
70
+ # Subclasses may override or supplement validate to perform validation on the list subject
71
+ #
72
+ # @param [RDF::N3::List] list
73
+ # @return [Boolean]
74
+ def validate(list)
75
+ if list.list? && list.valid?
76
+ true
77
+ else
78
+ log_error(NAME) {"operand is not a list: #{list.to_sxp}"}
79
+ false
80
+ end
81
+ end
82
+ end
83
+ end
@@ -3,7 +3,63 @@ module RDF::N3::Algebra::Log
3
3
  # All possible conclusions which can be drawn from a formula.
4
4
  #
5
5
  # The object of this function, a formula, is the set of conclusions which can be drawn from the subject formula, by successively applying any rules it contains to the data it contains. This is equivalent to cwm's "--think" command line function. It does use built-ins, so it may for example indirectly invoke other documents, validate signatures, etc.
6
- class Conclusion < SPARQL::Algebra::Operator::Binary
6
+ class Conclusion < RDF::N3::Algebra::ResourceOperator
7
7
  NAME = :logConclusion
8
+ URI = RDF::N3::Log.conclusion
9
+
10
+ ##
11
+ # Evaluates this operator by creating a new formula containing the triples generated by reasoning over the input formula using think.
12
+ #
13
+ # The subject is evaluated into an isolated repository so that conclusions evaluated when evaluating the subject are not necessarily conclusions resulting from evaluating this operator.
14
+ #
15
+ # @param [RDF::N3::Algebra:Formula] resource
16
+ # @return [RDF::N3::Algebra::Formula]
17
+ # @see RDF::N3::ListOperator#evaluate
18
+ def resolve(resource, position:)
19
+ return resource unless position == :subject
20
+
21
+ log_depth do
22
+ reasoner = RDF::N3::Reasoner.new(resource, **@options)
23
+ conclusions = RDF::N3::Repository.new
24
+ reasoner.execute(think: true) {|stmt| conclusions << stmt}
25
+
26
+ # The result is a formula containing the conclusions
27
+ form = RDF::N3::Algebra::Formula.from_enumerable(conclusions, **@options).deep_dup
28
+
29
+ log_info("#{NAME} resolved") {SXP::Generator.string form.to_sxp_bin}
30
+ form
31
+ end
32
+ end
33
+
34
+ ##
35
+ # To be valid, subject must be a formula, and object a formula or variable.
36
+ #
37
+ # @param [RDF::Term] subject
38
+ # @param [RDF::Term] object
39
+ # @return [Boolean]
40
+ def valid?(subject, object)
41
+ subject.formula? && (object.formula? || object.is_a?(RDF::Query::Variable))
42
+ end
43
+
44
+ ##
45
+ # Return subject operand.
46
+ #
47
+ # @return [RDF::Term]
48
+ def input_operand
49
+ operands.first
50
+ end
51
+
52
+ ##
53
+ # Yields statements, and de-asserts `inferred` from the subject.
54
+ #
55
+ # @yield [statement]
56
+ # each matching statement
57
+ # @yieldparam [RDF::Statement] solution
58
+ # @yieldreturn [void] ignored
59
+ def each(solutions:, &block)
60
+ super do |stmt|
61
+ block.call(RDF::Statement.from(stmt.to_quad))
62
+ end
63
+ end
8
64
  end
9
65
  end
@@ -3,7 +3,34 @@ module RDF::N3::Algebra::Log
3
3
  # A function to merge formulae: logical AND.
4
4
  #
5
5
  # The subject is a list of formulae. The object, which can be generated, is a formula containing a copy of each of the formulae in the list on the left. A cwm built-in function.
6
- class Conjunction < SPARQL::Algebra::Operator::Binary
6
+ class Conjunction < RDF::N3::Algebra::ListOperator
7
7
  NAME = :logConjunction
8
+ URI = RDF::N3::Log.conjunction
9
+
10
+ ##
11
+ # Evaluates this operator by creating a new formula containing the triples from each of the formulae in the list.
12
+ #
13
+ # @param [RDF::N3::List] list
14
+ # @return [RDF::N3::Algebra::Formula]
15
+ # @see RDF::N3::ListOperator#evaluate
16
+ def resolve(list)
17
+ form = RDF::N3::Algebra::Formula.new(graph_name: RDF::Node.intern(list.hash))
18
+ log_debug(NAME, "list hash") {form.graph_name}
19
+
20
+ list.each do |f|
21
+ form.operands.push(*f.operands)
22
+ end
23
+ form = form.dup
24
+ log_info(NAME, "result") {SXP::Generator.string form.to_sxp_bin}
25
+ form
26
+ end
27
+
28
+ ##
29
+ # Return subject operand.
30
+ #
31
+ # @return [RDF::Term]
32
+ def input_operand
33
+ operands.first
34
+ end
8
35
  end
9
36
  end
@@ -0,0 +1,34 @@
1
+ module RDF::N3::Algebra::Log
2
+ ##
3
+ # This connects a document and a string that represents it.
4
+ #
5
+ # (Cwm knows how to go get a document in order to evaluate this.)
6
+ #
7
+ # Note that the content-type of the information is not given and so must be known or guessed.
8
+ class Content < RDF::N3::Algebra::ResourceOperator
9
+ NAME = :logContent
10
+ URI = RDF::N3::Log.content
11
+
12
+ ##
13
+ # Reads the subject into the object.
14
+ #
15
+ # Returns nil if resource does not validate, given its position
16
+ #
17
+ # @param [RDF::N3::List] resource
18
+ # @return [RDF::Term]
19
+ def resolve(resource, position: :subject)
20
+ case position
21
+ when :subject
22
+ return nil unless resource.literal? || resource.uri?
23
+ content = begin
24
+ as_literal(RDF::Util::File.open_file(resource) {|f| f.read})
25
+ rescue IOError
26
+ nil
27
+ end
28
+ when :object
29
+ return nil unless resource.literal? || resource.variable?
30
+ resource
31
+ end
32
+ end
33
+ end
34
+ end