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,102 @@
|
|
1
|
+
module RDF::N3::Algebra::Log
|
2
|
+
##
|
3
|
+
# Logical implication.
|
4
|
+
#
|
5
|
+
# This is the relation between the antecedent (subject) and conclusion (object) of a rule. The application of a rule to a knowledge-base is as follows. For every substitution which, applied to the antecedent, gives a formula which is a subset of the knowledge-base, then the result of applying that same substitution to the conclusion may be added to the knowledge-base.
|
6
|
+
#
|
7
|
+
# related: See log:conclusion.
|
8
|
+
class Implies < SPARQL::Algebra::Operator::Binary
|
9
|
+
include SPARQL::Algebra::Query
|
10
|
+
include SPARQL::Algebra::Update
|
11
|
+
include RDF::N3::Algebra::Builtin
|
12
|
+
|
13
|
+
NAME = :logImplies
|
14
|
+
URI = RDF::N3::Log.implies
|
15
|
+
|
16
|
+
##
|
17
|
+
# Returns solutions from subject. Solutions are created by evaluating subject against `queryable`.
|
18
|
+
#
|
19
|
+
# Solutions are kept within this instance, and used for conclusions. Note that the evaluated solutions do not affect that of the invoking formula, as the solution spaces are disjoint.
|
20
|
+
#
|
21
|
+
# @param [RDF::Queryable] queryable
|
22
|
+
# the graph or repository to query
|
23
|
+
# @param [Hash{Symbol => Object}] options
|
24
|
+
# any additional keyword options
|
25
|
+
# @option options [RDF::Query::Solutions] solutions
|
26
|
+
# optional initial solutions for chained queries
|
27
|
+
# @return [RDF::Solutions] distinct solutions
|
28
|
+
def execute(queryable, solutions:, **options)
|
29
|
+
@queryable = queryable
|
30
|
+
@solutions = RDF::Query::Solutions(solutions.map do |solution|
|
31
|
+
log_debug(NAME, "solution") {SXP::Generator.string(solution.to_sxp_bin)}
|
32
|
+
subject = operand(0).evaluate(solution.bindings, formulae: formulae)
|
33
|
+
object = operand(1).evaluate(solution.bindings, formulae: formulae)
|
34
|
+
log_info(NAME, "subject") {SXP::Generator.string(subject.to_sxp_bin)}
|
35
|
+
log_info(NAME, "object") {SXP::Generator.string(object.to_sxp_bin)}
|
36
|
+
|
37
|
+
# Nothing to do if variables aren't resolved.
|
38
|
+
next unless subject && object
|
39
|
+
|
40
|
+
solns = log_depth {subject.execute(queryable, solutions: RDF::Query::Solutions(solution), **options)}
|
41
|
+
|
42
|
+
# Execute object as well (typically used for log:outputString)
|
43
|
+
solns.each do |soln|
|
44
|
+
log_depth {object.execute(queryable, solutions: RDF::Query::Solutions(soln), **options)}
|
45
|
+
end
|
46
|
+
|
47
|
+
# filter solutions where not all variables in antecedant are bound.
|
48
|
+
vars = subject.universal_vars
|
49
|
+
solns = RDF::Query::Solutions(solns.to_a.select do |soln|
|
50
|
+
vars.all? {|v| soln.bound?(v)}
|
51
|
+
end)
|
52
|
+
solns
|
53
|
+
end.flatten.compact.uniq)
|
54
|
+
log_info(NAME) {SXP::Generator.string(@solutions.to_sxp_bin)}
|
55
|
+
|
56
|
+
# Return original solutions, without bindings
|
57
|
+
solutions
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# Clear out any cached solutions.
|
62
|
+
# This principaly is for log:conclusions
|
63
|
+
def clear_solutions
|
64
|
+
super
|
65
|
+
@solutions = nil
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Yields statements from the object based on solutions determined from the subject. Each solution formed by querying `queryable` from the subject is used to create a graph, which must be a subgraph of `queryable`. If so, that solution is used to generate triples from the object formula which are yielded.
|
70
|
+
#
|
71
|
+
# @yield [statement]
|
72
|
+
# each matching statement
|
73
|
+
# @yieldparam [RDF::Statement] solution
|
74
|
+
# @yieldreturn [void] ignored
|
75
|
+
def each(solutions: RDF::Query::Solutions(), &block)
|
76
|
+
# Merge solutions in with those for the evaluation of this implication
|
77
|
+
# Clear out solutions so they don't get remembered erroneously.
|
78
|
+
solutions, @solutions = Array(@solutions), nil
|
79
|
+
log_depth do
|
80
|
+
super(solutions: RDF::Query::Solutions(RDF::Query::Solution.new), &block)
|
81
|
+
|
82
|
+
solutions.each do |solution|
|
83
|
+
log_info("(logImplies each) solution") {SXP::Generator.string solution.to_sxp_bin}
|
84
|
+
object = operand(1).evaluate(solution.bindings, formulae: formulae)
|
85
|
+
log_info("(logImplies each) object") {SXP::Generator.string object.to_sxp_bin}
|
86
|
+
|
87
|
+
# Yield inferred statements
|
88
|
+
log_depth do
|
89
|
+
object.each(solutions: RDF::Query::Solutions(solution)) do |statement|
|
90
|
+
log_debug(("(logImplies each) infer\s")) {statement.to_sxp}
|
91
|
+
block.call(RDF::Statement.from(statement.to_quad, inferred: true))
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Graph name associated with this operation, using the name of the parent
|
99
|
+
# @return [RDF::Resource]
|
100
|
+
def graph_name; parent.graph_name; end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module RDF::N3::Algebra::Log
|
2
|
+
##
|
3
|
+
# The subject formula includes the object formula.
|
4
|
+
#
|
5
|
+
# Formula A includes formula B if there exists some substitution which when applied to B creates a formula B' such that for every statement in B' is also in A, every variable universally (or existentially) quantified in B' is quantified in the same way in A.
|
6
|
+
#
|
7
|
+
# Variable substitution is applied recursively to nested compound terms such as formulae, lists and sets.
|
8
|
+
#
|
9
|
+
# (Understood natively by cwm when in in the antecedent of a rule. You can use this to peer inside nested formulae.)
|
10
|
+
class Includes < RDF::N3::Algebra::ResourceOperator
|
11
|
+
NAME = :logIncludes
|
12
|
+
URI = RDF::N3::Log.includes
|
13
|
+
|
14
|
+
##
|
15
|
+
# Both subject and object must be formulae.
|
16
|
+
#
|
17
|
+
# @param [RDF::Term] resource
|
18
|
+
# @param [:subject, :object] position
|
19
|
+
# @return [RDF::Term]
|
20
|
+
# @see RDF::N3::ResourceOperator#evaluate
|
21
|
+
def resolve(resource, position:)
|
22
|
+
resource if resource.formula?
|
23
|
+
end
|
24
|
+
|
25
|
+
# Both subject and object are inputs.
|
26
|
+
def input_operand
|
27
|
+
RDF::N3::List.new(values: operands)
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Creates a repository constructed by substituting variables and in that subject with known IRIs and queries object against that repository. Either retuns a single solution, or no solutions.
|
32
|
+
#
|
33
|
+
# @note this does allow object to have variables not in the subject, if they could have been substituted away.
|
34
|
+
#
|
35
|
+
# @param [RDF::N3::Algebra::Formula] subject
|
36
|
+
# a formula
|
37
|
+
# @param [RDF::N3::Algebra::Formula] object
|
38
|
+
# a formula
|
39
|
+
# @return [RDF::Literal::Boolean]
|
40
|
+
def apply(subject, object)
|
41
|
+
subject_var_map = subject.variables.values.inject({}) {|memo, v| memo.merge(v => RDF::URI(v.name))}
|
42
|
+
object_vars = object.variables.keys
|
43
|
+
log_debug(NAME, "subject var map") {SXP::Generator.string(subject_var_map.to_sxp_bin)}
|
44
|
+
log_debug(NAME, "object vars") {SXP::Generator.string(object_vars.to_sxp_bin)}
|
45
|
+
# create a queryable from subject, replacing variables with IRIs for thsoe variables.
|
46
|
+
queryable = RDF::Repository.new do |r|
|
47
|
+
log_depth do
|
48
|
+
subject.each do |stmt|
|
49
|
+
parts = stmt.to_quad.map do |part|
|
50
|
+
part.is_a?(RDF::Query::Variable) ? subject_var_map.fetch(part) : part
|
51
|
+
end
|
52
|
+
r << RDF::Statement.from(parts)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Query object against subject
|
58
|
+
solns = log_depth {queryable.query(object, **@options)}
|
59
|
+
log_info("(#{NAME} solutions)") {SXP::Generator.string solns.to_sxp_bin}
|
60
|
+
|
61
|
+
if !solns.empty? && (object_vars - solns.variable_names).empty?
|
62
|
+
# Return solution
|
63
|
+
solns.first
|
64
|
+
else
|
65
|
+
# Return false,
|
66
|
+
RDF::Literal::FALSE
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module RDF::N3::Algebra::Log
|
2
|
+
##
|
3
|
+
# The subject formula, expressed as N3, gives this string.
|
4
|
+
class N3String < RDF::N3::Algebra::ResourceOperator
|
5
|
+
NAME = :logN3String
|
6
|
+
URI = RDF::N3::Log.n3String
|
7
|
+
|
8
|
+
##
|
9
|
+
# Serializes the subject formula into an N3 string representation.
|
10
|
+
#
|
11
|
+
# @param [RDF::N3::List] resource
|
12
|
+
# @return [RDF::Term]
|
13
|
+
def resolve(resource, position: :subject)
|
14
|
+
case position
|
15
|
+
when :subject
|
16
|
+
return nil unless resource.formula?
|
17
|
+
as_literal(RDF::N3::Writer.buffer {|w| resource.each {|st| w << st}})
|
18
|
+
when :object
|
19
|
+
return nil unless resource.literal? || resource.variable?
|
20
|
+
resource
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# Subject must evaluate to a formula and object to a literal.
|
26
|
+
#
|
27
|
+
# @param [RDF::Term] subject
|
28
|
+
# @param [RDF::Term] object
|
29
|
+
# @return [Boolean]
|
30
|
+
def valid?(subject, object)
|
31
|
+
subject.formula? && (object.variable? || object.literal?)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module RDF::N3::Algebra::Log
|
2
|
+
##
|
3
|
+
# Equality in this sense is actually the same URI. A cwm built-in logical operator.
|
4
|
+
class NotEqualTo < SPARQL::Algebra::Operator::SameTerm
|
5
|
+
include RDF::N3::Algebra::Builtin
|
6
|
+
NAME = :logNotEqualTo
|
7
|
+
URI = RDF::N3::Log.notEqualto
|
8
|
+
|
9
|
+
##
|
10
|
+
# Returns `true` if the operands are not the same RDF term; returns
|
11
|
+
# `false` otherwise.
|
12
|
+
#
|
13
|
+
# @param [RDF::Term] term1
|
14
|
+
# an RDF term
|
15
|
+
# @param [RDF::Term] term2
|
16
|
+
# an RDF term
|
17
|
+
# @return [RDF::Literal::Boolean] `true` or `false`
|
18
|
+
# @raise [TypeError] if either operand is unbound
|
19
|
+
def apply(term1, term2)
|
20
|
+
RDF::Literal(!term1.eql?(term2))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module RDF::N3::Algebra::Log
|
2
|
+
##
|
3
|
+
# The object formula is NOT a subset of subject. True iff log:includes is false. The converse of log:includes.
|
4
|
+
# (Understood natively by cwm. The subject formula may contain variables.)
|
5
|
+
#
|
6
|
+
# (In cwm, variables must of course end up getting bound before the log:include test can be done, or an infinite result set would result)
|
7
|
+
#
|
8
|
+
# Related: See includes
|
9
|
+
class NotIncludes < Includes
|
10
|
+
NAME = :logNotIncludes
|
11
|
+
URI = RDF::N3::Log.notIncludes
|
12
|
+
|
13
|
+
##
|
14
|
+
# Uses log:includes and returns a solution if log:includes fails
|
15
|
+
#
|
16
|
+
# @param [RDF::Queryable] queryable
|
17
|
+
# the graph or repository to query
|
18
|
+
# @param [Hash{Symbol => Object}] options
|
19
|
+
# any additional keyword options
|
20
|
+
# @option options [RDF::Query::Solutions] solutions
|
21
|
+
# optional initial solutions for chained queries
|
22
|
+
# @return [RDF::Solutions] distinct solutions
|
23
|
+
def execute(queryable, solutions:, **options)
|
24
|
+
super.empty? ? RDF::Query::Solutions(RDF::Query::Solution.new) : RDF::Query::Solutions.new
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module RDF::N3::Algebra::Log
|
2
|
+
##
|
3
|
+
# The subject is a key and the object is a string, where the strings are to be output in the order of the keys.
|
4
|
+
class OutputString < RDF::N3::Algebra::ResourceOperator
|
5
|
+
NAME = :logOutputString
|
6
|
+
URI = RDF::N3::Log.outputString
|
7
|
+
|
8
|
+
##
|
9
|
+
# Resolves inputs as strings.
|
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
|
+
SPARQL::Algebra::Expression.cast(RDF::XSD.string, resource) if resource.term?
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Returns `term2`, but adds `term2` as an output keyed on `term1`.
|
21
|
+
#
|
22
|
+
# @param [RDF::Term] term1
|
23
|
+
# an RDF term
|
24
|
+
# @param [RDF::Term] term2
|
25
|
+
# an RDF term
|
26
|
+
# @return [RDF::Literal::Boolean] `true` or `false`
|
27
|
+
# @raise [TypeError] if either operand is not an RDF term or operands are not comperable
|
28
|
+
#
|
29
|
+
# @see RDF::Term#==
|
30
|
+
def apply(term1, term2)
|
31
|
+
(@options[:strings][term1.to_s] ||= []) << term2.to_s
|
32
|
+
term2
|
33
|
+
end
|
34
|
+
|
35
|
+
# Both subject and object are inputs.
|
36
|
+
def input_operand
|
37
|
+
RDF::N3::List.new(values: operands)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module RDF::N3::Algebra::Log
|
2
|
+
##
|
3
|
+
# The subject string, parsed as N3, gives this formula.
|
4
|
+
class ParsedAsN3 < RDF::N3::Algebra::ResourceOperator
|
5
|
+
NAME = :logParsedAsN3
|
6
|
+
URI = RDF::N3::Log.parsedAsN3
|
7
|
+
|
8
|
+
##
|
9
|
+
# Parses the subject into a new formula.
|
10
|
+
#
|
11
|
+
# Returns nil if resource does not validate, given its position
|
12
|
+
#
|
13
|
+
# @param [RDF::N3::List] resource
|
14
|
+
# @return [RDF::Term]
|
15
|
+
def resolve(resource, position: :subject)
|
16
|
+
case position
|
17
|
+
when :subject
|
18
|
+
return nil unless resource.literal?
|
19
|
+
begin
|
20
|
+
repo = RDF::N3::Repository.new
|
21
|
+
repo << RDF::N3::Reader.new(resource.to_s, **@options.merge(list_terms: true, logger: false))
|
22
|
+
log_debug("logParsedAsN3") {SXP::Generator.string repo.statements.to_sxp_bin}
|
23
|
+
content_hash = resource.hash # used as name of resulting formula
|
24
|
+
form = RDF::N3::Algebra::Formula.from_enumerable(repo, graph_name: RDF::Node.intern(content_hash))
|
25
|
+
log_info(NAME) {"form hash (#{resource}): #{form.hash}"}
|
26
|
+
form
|
27
|
+
rescue RDF::ReaderError
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
when :object
|
31
|
+
return nil unless resource.literal? || resource.is_a?(RDF::Query::Variable)
|
32
|
+
resource
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module RDF::N3::Algebra::Log
|
2
|
+
##
|
3
|
+
# The log:semantics of a document is the formula. achieved by parsing representation of the document. For a document in Notation3, log:semantics is the log:parsedAsN3 of the log:contents of the document. For a document in RDF/XML, it is parsed according to the RDF/XML specification to yield an RDF formula (a subclass of N3 log:Formula).
|
4
|
+
#
|
5
|
+
# [Aside: Philosophers will be distracted here into worrying about the meaning of meaning. At least we didn't call this function "meaning"! In as much as N3 is used as an interlingua for interoperability for different systems, this for an N3 based system is the meaning expressed by a document.]
|
6
|
+
#
|
7
|
+
# (Cwm knows how to go get a document and parse N3 and RDF/XML it in order to evaluate this. Other languages for web documents may be defined whose N3 semantics are therefore also calculable, and so they could be added in due course. See for example GRDDL, RDFa, etc)
|
8
|
+
class Semantics < RDF::N3::Algebra::ResourceOperator
|
9
|
+
NAME = :logSemantics
|
10
|
+
URI = RDF::N3::Log.semantics
|
11
|
+
|
12
|
+
##
|
13
|
+
# Parses the subject into a new formula.
|
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
|
+
begin
|
24
|
+
repo = RDF::N3::Repository.new
|
25
|
+
repo << RDF::Reader.open(resource, **@options.merge(list_terms: true, base_uri: resource, logger: false))
|
26
|
+
content_hash = repo.statements.hash # used as name of resulting formula
|
27
|
+
form = RDF::N3::Algebra::Formula.from_enumerable(repo, graph_name: RDF::Node.intern(content_hash))
|
28
|
+
log_debug(NAME) {"form hash (#{resource}): #{form.hash}"}
|
29
|
+
form
|
30
|
+
rescue IOError, RDF::ReaderError => e
|
31
|
+
log_error(NAME) {"error loading #{resource}: #{e}"}
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
when :object
|
35
|
+
return nil unless resource.literal? || resource.variable?
|
36
|
+
resource
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module RDF::N3::Algebra::Math
|
2
|
+
##
|
3
|
+
# The object is calulated as the absolute value of the subject.
|
4
|
+
#
|
5
|
+
# @see https://www.w3.org/TR/xpath-functions/#func-abs
|
6
|
+
class AbsoluteValue < RDF::N3::Algebra::ResourceOperator
|
7
|
+
NAME = :mathAbsoluteValue
|
8
|
+
URI = RDF::N3::Math.absoluteValue
|
9
|
+
|
10
|
+
##
|
11
|
+
# The math:absoluteValue operator takes string or number and calculates its absolute value.
|
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
|
+
as_literal(resource.as_number.abs)
|
22
|
+
when :object
|
23
|
+
return nil unless resource.literal? || resource.variable?
|
24
|
+
resource
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Input is either the subject or object
|
30
|
+
#
|
31
|
+
# @return [RDF::Term]
|
32
|
+
def input_operand
|
33
|
+
RDF::N3::List.new(values: operands)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module RDF::N3::Algebra::Math
|
2
|
+
##
|
3
|
+
# The object is calulated as the arc cosine value of the subject.
|
4
|
+
class ACos < RDF::N3::Algebra::ResourceOperator
|
5
|
+
NAME = :mathACos
|
6
|
+
URI = RDF::N3::Math.acos
|
7
|
+
|
8
|
+
##
|
9
|
+
# The math:acos operator takes string or number and calculates its arc cosine.
|
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
|
+
as_literal(Math.acos(resource.as_number.object))
|
20
|
+
when :object
|
21
|
+
return nil unless resource.literal? || resource.variable?
|
22
|
+
resource
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|