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.
- checksums.yaml +4 -4
- data/README.md +148 -69
- data/UNLICENSE +1 -1
- data/VERSION +1 -1
- data/lib/rdf/n3.rb +8 -8
- data/lib/rdf/n3/algebra.rb +147 -68
- data/lib/rdf/n3/algebra/builtin.rb +79 -0
- data/lib/rdf/n3/algebra/formula.rb +355 -94
- data/lib/rdf/n3/algebra/list/append.rb +33 -4
- data/lib/rdf/n3/algebra/list/first.rb +24 -0
- data/lib/rdf/n3/algebra/list/in.rb +42 -3
- data/lib/rdf/n3/algebra/list/last.rb +17 -4
- data/lib/rdf/n3/algebra/list/length.rb +24 -0
- data/lib/rdf/n3/algebra/list/member.rb +39 -2
- data/lib/rdf/n3/algebra/list_operator.rb +83 -0
- data/lib/rdf/n3/algebra/log/conclusion.rb +57 -1
- data/lib/rdf/n3/algebra/log/conjunction.rb +28 -1
- 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 +55 -30
- data/lib/rdf/n3/algebra/log/includes.rb +58 -1
- 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 +34 -3
- data/lib/rdf/n3/algebra/math/equal_to.rb +54 -0
- data/lib/rdf/n3/algebra/math/exponentiation.rb +29 -3
- 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 +31 -2
- 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 +14 -3
- data/lib/rdf/n3/algebra/math/quotient.rb +30 -3
- data/lib/rdf/n3/algebra/math/remainder.rb +29 -3
- data/lib/rdf/n3/algebra/math/rounded.rb +20 -3
- 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 +35 -4
- 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 +21 -3
- data/lib/rdf/n3/algebra/str/contains.rb +28 -4
- 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 +12 -4
- 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 +33 -5
- 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 +28 -5
- data/lib/rdf/n3/algebra/str/scrape.rb +31 -5
- 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 +180 -21
- data/lib/rdf/n3/format.rb +65 -0
- data/lib/rdf/n3/list.rb +630 -0
- data/lib/rdf/n3/reader.rb +762 -485
- data/lib/rdf/n3/reasoner.rb +57 -68
- 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 +35 -7
- data/lib/rdf/n3/writer.rb +208 -148
- metadata +110 -52
- data/AUTHORS +0 -1
- data/History.markdown +0 -99
- data/lib/rdf/n3/algebra/log/equalTo.rb +0 -7
- data/lib/rdf/n3/algebra/log/notEqualTo.rb +0 -7
- data/lib/rdf/n3/algebra/log/notIncludes.rb +0 -12
- data/lib/rdf/n3/algebra/log/outputString.rb +0 -7
- data/lib/rdf/n3/algebra/math/absoluteValue.rb +0 -9
- data/lib/rdf/n3/algebra/math/equalTo.rb +0 -9
- data/lib/rdf/n3/algebra/math/greaterThan.rb +0 -9
- data/lib/rdf/n3/algebra/math/integerQuotient.rb +0 -9
- data/lib/rdf/n3/algebra/math/lessThan.rb +0 -9
- data/lib/rdf/n3/algebra/math/memberCount.rb +0 -9
- data/lib/rdf/n3/algebra/math/notEqualTo.rb +0 -9
- data/lib/rdf/n3/algebra/math/notGreaterThan.rb +0 -9
- data/lib/rdf/n3/algebra/math/notLessThan.rb +0 -9
- data/lib/rdf/n3/algebra/str/containsIgnoringCase.rb +0 -9
- data/lib/rdf/n3/algebra/str/endsWith.rb +0 -9
- data/lib/rdf/n3/algebra/str/equalIgnoringCase.rb +0 -9
- data/lib/rdf/n3/algebra/str/greaterThan.rb +0 -9
- data/lib/rdf/n3/algebra/str/lessThan.rb +0 -9
- data/lib/rdf/n3/algebra/str/notEqualIgnoringCase.rb +0 -9
- data/lib/rdf/n3/algebra/str/notGreaterThan.rb +0 -9
- data/lib/rdf/n3/algebra/str/notLessThan.rb +0 -9
- data/lib/rdf/n3/algebra/str/notMatches.rb +0 -9
- data/lib/rdf/n3/algebra/str/startsWith.rb +0 -56
- 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 -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
|
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 <
|
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
|
-
|
5
|
-
|
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
|
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 <
|
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
|
4
|
-
class Member <
|
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 <
|
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 <
|
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
|