rdf-n3 2.2.0 → 3.1.2
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.
- checksums.yaml +5 -5
- data/README.md +192 -69
- data/UNLICENSE +1 -1
- data/VERSION +1 -1
- data/lib/rdf/n3.rb +11 -8
- data/lib/rdf/n3/algebra.rb +204 -0
- data/lib/rdf/n3/algebra/builtin.rb +79 -0
- data/lib/rdf/n3/algebra/formula.rb +446 -0
- data/lib/rdf/n3/algebra/list/append.rb +42 -0
- data/lib/rdf/n3/algebra/list/first.rb +24 -0
- data/lib/rdf/n3/algebra/list/in.rb +48 -0
- data/lib/rdf/n3/algebra/list/last.rb +24 -0
- data/lib/rdf/n3/algebra/list/length.rb +24 -0
- data/lib/rdf/n3/algebra/list/member.rb +44 -0
- data/lib/rdf/n3/algebra/list_operator.rb +83 -0
- data/lib/rdf/n3/algebra/log/conclusion.rb +65 -0
- data/lib/rdf/n3/algebra/log/conjunction.rb +36 -0
- data/lib/rdf/n3/algebra/log/content.rb +34 -0
- data/lib/rdf/n3/algebra/log/equal_to.rb +34 -0
- data/lib/rdf/n3/algebra/log/implies.rb +102 -0
- data/lib/rdf/n3/algebra/log/includes.rb +70 -0
- data/lib/rdf/n3/algebra/log/n3_string.rb +34 -0
- data/lib/rdf/n3/algebra/log/not_equal_to.rb +23 -0
- data/lib/rdf/n3/algebra/log/not_includes.rb +27 -0
- data/lib/rdf/n3/algebra/log/output_string.rb +40 -0
- data/lib/rdf/n3/algebra/log/parsed_as_n3.rb +36 -0
- data/lib/rdf/n3/algebra/log/semantics.rb +40 -0
- data/lib/rdf/n3/algebra/math/absolute_value.rb +36 -0
- data/lib/rdf/n3/algebra/math/acos.rb +26 -0
- data/lib/rdf/n3/algebra/math/acosh.rb +26 -0
- data/lib/rdf/n3/algebra/math/asin.rb +26 -0
- data/lib/rdf/n3/algebra/math/asinh.rb +26 -0
- data/lib/rdf/n3/algebra/math/atan.rb +26 -0
- data/lib/rdf/n3/algebra/math/atanh.rb +26 -0
- data/lib/rdf/n3/algebra/math/ceiling.rb +28 -0
- data/lib/rdf/n3/algebra/math/cos.rb +40 -0
- data/lib/rdf/n3/algebra/math/cosh.rb +38 -0
- data/lib/rdf/n3/algebra/math/difference.rb +40 -0
- data/lib/rdf/n3/algebra/math/equal_to.rb +54 -0
- data/lib/rdf/n3/algebra/math/exponentiation.rb +35 -0
- data/lib/rdf/n3/algebra/math/floor.rb +28 -0
- data/lib/rdf/n3/algebra/math/greater_than.rb +41 -0
- data/lib/rdf/n3/algebra/math/less_than.rb +41 -0
- data/lib/rdf/n3/algebra/math/negation.rb +38 -0
- data/lib/rdf/n3/algebra/math/not_equal_to.rb +25 -0
- data/lib/rdf/n3/algebra/math/not_greater_than.rb +25 -0
- data/lib/rdf/n3/algebra/math/not_less_than.rb +25 -0
- data/lib/rdf/n3/algebra/math/product.rb +20 -0
- data/lib/rdf/n3/algebra/math/quotient.rb +36 -0
- data/lib/rdf/n3/algebra/math/remainder.rb +35 -0
- data/lib/rdf/n3/algebra/math/rounded.rb +26 -0
- data/lib/rdf/n3/algebra/math/sin.rb +40 -0
- data/lib/rdf/n3/algebra/math/sinh.rb +38 -0
- data/lib/rdf/n3/algebra/math/sum.rb +40 -0
- data/lib/rdf/n3/algebra/math/tan.rb +40 -0
- data/lib/rdf/n3/algebra/math/tanh.rb +38 -0
- data/lib/rdf/n3/algebra/not_implemented.rb +13 -0
- data/lib/rdf/n3/algebra/resource_operator.rb +123 -0
- data/lib/rdf/n3/algebra/str/concatenation.rb +27 -0
- data/lib/rdf/n3/algebra/str/contains.rb +33 -0
- data/lib/rdf/n3/algebra/str/contains_ignoring_case.rb +33 -0
- data/lib/rdf/n3/algebra/str/ends_with.rb +33 -0
- data/lib/rdf/n3/algebra/str/equal_ignoring_case.rb +34 -0
- data/lib/rdf/n3/algebra/str/format.rb +17 -0
- data/lib/rdf/n3/algebra/str/greater_than.rb +38 -0
- data/lib/rdf/n3/algebra/str/less_than.rb +33 -0
- data/lib/rdf/n3/algebra/str/matches.rb +37 -0
- data/lib/rdf/n3/algebra/str/not_equal_ignoring_case.rb +17 -0
- data/lib/rdf/n3/algebra/str/not_greater_than.rb +17 -0
- data/lib/rdf/n3/algebra/str/not_less_than.rb +17 -0
- data/lib/rdf/n3/algebra/str/not_matches.rb +18 -0
- data/lib/rdf/n3/algebra/str/replace.rb +35 -0
- data/lib/rdf/n3/algebra/str/scrape.rb +35 -0
- data/lib/rdf/n3/algebra/str/starts_with.rb +33 -0
- data/lib/rdf/n3/algebra/time/day.rb +35 -0
- data/lib/rdf/n3/algebra/time/day_of_week.rb +27 -0
- data/lib/rdf/n3/algebra/time/gm_time.rb +29 -0
- data/lib/rdf/n3/algebra/time/hour.rb +35 -0
- data/lib/rdf/n3/algebra/time/in_seconds.rb +59 -0
- data/lib/rdf/n3/algebra/time/local_time.rb +29 -0
- data/lib/rdf/n3/algebra/time/minute.rb +35 -0
- data/lib/rdf/n3/algebra/time/month.rb +35 -0
- data/lib/rdf/n3/algebra/time/second.rb +35 -0
- data/lib/rdf/n3/algebra/time/timezone.rb +36 -0
- data/lib/rdf/n3/algebra/time/year.rb +29 -0
- data/lib/rdf/n3/extensions.rb +221 -0
- data/lib/rdf/n3/format.rb +66 -1
- data/lib/rdf/n3/list.rb +630 -0
- data/lib/rdf/n3/reader.rb +834 -492
- data/lib/rdf/n3/reasoner.rb +282 -0
- data/lib/rdf/n3/refinements.rb +178 -0
- data/lib/rdf/n3/repository.rb +332 -0
- data/lib/rdf/n3/terminals.rb +80 -0
- data/lib/rdf/n3/vocab.rb +36 -3
- data/lib/rdf/n3/writer.rb +476 -239
- metadata +187 -68
- data/AUTHORS +0 -1
- data/History.markdown +0 -99
- data/lib/rdf/n3/patches/array_hacks.rb +0 -53
- data/lib/rdf/n3/reader/meta.rb +0 -641
- data/lib/rdf/n3/reader/parser.rb +0 -237
@@ -0,0 +1,42 @@
|
|
1
|
+
module RDF::N3::Algebra::List
|
2
|
+
##
|
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
|
+
#
|
5
|
+
# @example
|
6
|
+
# ( (1 2) (3 4) ) list:append (1 2 3 4).
|
7
|
+
#
|
8
|
+
# The object can be calculated as a function of the subject.
|
9
|
+
class Append < RDF::N3::Algebra::ListOperator
|
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
|
41
|
+
end
|
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
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module RDF::N3::Algebra::List
|
2
|
+
##
|
3
|
+
# Iff the object is a list and the subject is in that list, then this is true.
|
4
|
+
#
|
5
|
+
# @example
|
6
|
+
# { 1 list:in ( 1 2 3 4 5 ) } => { :test4a a :SUCCESS }.
|
7
|
+
class In < RDF::N3::Algebra::ListOperator
|
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
|
47
|
+
end
|
48
|
+
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:last 6 } => { :test1 a :SUCCESS }.
|
7
|
+
#
|
8
|
+
# The object can be calculated as a function of the list.
|
9
|
+
class Last < RDF::N3::Algebra::ListOperator
|
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
|
23
|
+
end
|
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
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module RDF::N3::Algebra::List
|
2
|
+
##
|
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
|
+
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
|
43
|
+
end
|
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
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module RDF::N3::Algebra::Log
|
2
|
+
##
|
3
|
+
# All possible conclusions which can be drawn from a formula.
|
4
|
+
#
|
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 < RDF::N3::Algebra::ResourceOperator
|
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
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module RDF::N3::Algebra::Log
|
2
|
+
##
|
3
|
+
# A function to merge formulae: logical AND.
|
4
|
+
#
|
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 < RDF::N3::Algebra::ListOperator
|
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
|
35
|
+
end
|
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
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module RDF::N3::Algebra::Log
|
2
|
+
##
|
3
|
+
# True if the subject and object are the same RDF node (symbol or literal). Do not confuse with owl:sameAs. A cwm built-in logical operator, RDF graph level.
|
4
|
+
class EqualTo < RDF::N3::Algebra::ResourceOperator
|
5
|
+
NAME = :logEqualTo
|
6
|
+
URI = RDF::N3::Log.equalTo
|
7
|
+
|
8
|
+
##
|
9
|
+
# Resolves inputs as terms.
|
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.term?
|
17
|
+
end
|
18
|
+
|
19
|
+
# Both subject and object are inputs.
|
20
|
+
def input_operand
|
21
|
+
RDF::N3::List.new(values: operands)
|
22
|
+
end
|
23
|
+
|
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.sameTerm?(right))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|