sparql 0.0.1 → 0.0.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.
Files changed (84) hide show
  1. data/AUTHORS +3 -0
  2. data/CREDITS +0 -0
  3. data/README.markdown +103 -53
  4. data/UNLICENSE +24 -0
  5. data/VERSION +1 -0
  6. data/bin/sparql +87 -0
  7. data/lib/sparql.rb +105 -22
  8. data/lib/sparql/algebra.rb +369 -0
  9. data/lib/sparql/algebra/evaluatable.rb +37 -0
  10. data/lib/sparql/algebra/expression.rb +284 -0
  11. data/lib/sparql/algebra/extensions.rb +159 -0
  12. data/lib/sparql/algebra/operator.rb +492 -0
  13. data/lib/sparql/algebra/operator/add.rb +34 -0
  14. data/lib/sparql/algebra/operator/and.rb +65 -0
  15. data/lib/sparql/algebra/operator/asc.rb +29 -0
  16. data/lib/sparql/algebra/operator/ask.rb +46 -0
  17. data/lib/sparql/algebra/operator/base.rb +46 -0
  18. data/lib/sparql/algebra/operator/bgp.rb +26 -0
  19. data/lib/sparql/algebra/operator/bound.rb +48 -0
  20. data/lib/sparql/algebra/operator/compare.rb +84 -0
  21. data/lib/sparql/algebra/operator/construct.rb +85 -0
  22. data/lib/sparql/algebra/operator/dataset.rb +77 -0
  23. data/lib/sparql/algebra/operator/datatype.rb +42 -0
  24. data/lib/sparql/algebra/operator/desc.rb +17 -0
  25. data/lib/sparql/algebra/operator/describe.rb +71 -0
  26. data/lib/sparql/algebra/operator/distinct.rb +50 -0
  27. data/lib/sparql/algebra/operator/divide.rb +43 -0
  28. data/lib/sparql/algebra/operator/equal.rb +32 -0
  29. data/lib/sparql/algebra/operator/exprlist.rb +52 -0
  30. data/lib/sparql/algebra/operator/filter.rb +71 -0
  31. data/lib/sparql/algebra/operator/graph.rb +28 -0
  32. data/lib/sparql/algebra/operator/greater_than.rb +32 -0
  33. data/lib/sparql/algebra/operator/greater_than_or_equal.rb +33 -0
  34. data/lib/sparql/algebra/operator/is_blank.rb +35 -0
  35. data/lib/sparql/algebra/operator/is_iri.rb +37 -0
  36. data/lib/sparql/algebra/operator/is_literal.rb +36 -0
  37. data/lib/sparql/algebra/operator/join.rb +67 -0
  38. data/lib/sparql/algebra/operator/lang.rb +29 -0
  39. data/lib/sparql/algebra/operator/lang_matches.rb +53 -0
  40. data/lib/sparql/algebra/operator/left_join.rb +95 -0
  41. data/lib/sparql/algebra/operator/less_than.rb +32 -0
  42. data/lib/sparql/algebra/operator/less_than_or_equal.rb +32 -0
  43. data/lib/sparql/algebra/operator/minus.rb +31 -0
  44. data/lib/sparql/algebra/operator/multiply.rb +34 -0
  45. data/lib/sparql/algebra/operator/not.rb +35 -0
  46. data/lib/sparql/algebra/operator/not_equal.rb +26 -0
  47. data/lib/sparql/algebra/operator/or.rb +65 -0
  48. data/lib/sparql/algebra/operator/order.rb +69 -0
  49. data/lib/sparql/algebra/operator/plus.rb +31 -0
  50. data/lib/sparql/algebra/operator/prefix.rb +45 -0
  51. data/lib/sparql/algebra/operator/project.rb +46 -0
  52. data/lib/sparql/algebra/operator/reduced.rb +47 -0
  53. data/lib/sparql/algebra/operator/regex.rb +70 -0
  54. data/lib/sparql/algebra/operator/same_term.rb +46 -0
  55. data/lib/sparql/algebra/operator/slice.rb +60 -0
  56. data/lib/sparql/algebra/operator/str.rb +35 -0
  57. data/lib/sparql/algebra/operator/subtract.rb +32 -0
  58. data/lib/sparql/algebra/operator/union.rb +55 -0
  59. data/lib/sparql/algebra/query.rb +99 -0
  60. data/lib/sparql/algebra/sxp_extensions.rb +35 -0
  61. data/lib/sparql/algebra/version.rb +20 -0
  62. data/lib/sparql/extensions.rb +102 -0
  63. data/lib/sparql/grammar.rb +298 -0
  64. data/lib/sparql/grammar/lexer.rb +609 -0
  65. data/lib/sparql/grammar/parser.rb +1383 -0
  66. data/lib/sparql/grammar/parser/meta.rb +1801 -0
  67. data/lib/sparql/results.rb +220 -0
  68. data/lib/sparql/version.rb +20 -0
  69. metadata +232 -62
  70. data/Rakefile +0 -22
  71. data/coverage/index.html +0 -252
  72. data/coverage/lib-sparql-execute_sparql_rb.html +0 -621
  73. data/coverage/lib-sparql_rb.html +0 -622
  74. data/lib/sparql/execute_sparql.rb +0 -27
  75. data/lib/sparql/sparql.treetop +0 -159
  76. data/sparql.gemspec +0 -16
  77. data/spec/spec.opts +0 -2
  78. data/spec/spec_helper.rb +0 -24
  79. data/spec/unit/graph_parsing_spec.rb +0 -76
  80. data/spec/unit/iri_parsing_spec.rb +0 -46
  81. data/spec/unit/prefixed_names_parsing_spec.rb +0 -40
  82. data/spec/unit/primitives_parsing_spec.rb +0 -26
  83. data/spec/unit/sparql_parsing_spec.rb +0 -72
  84. data/spec/unit/variables_parsing_spec.rb +0 -36
@@ -0,0 +1,32 @@
1
+ module SPARQL; module Algebra
2
+ class Operator
3
+ ##
4
+ # The SPARQL relational `<` (less than) comparison operator.
5
+ #
6
+ # @example
7
+ # (< ?x ?y)
8
+ #
9
+ # @see http://www.w3.org/TR/rdf-sparql-query/#OperatorMapping
10
+ # @see http://www.w3.org/TR/xpath-functions/#func-compare
11
+ # @see http://www.w3.org/TR/xpath-functions/#func-numeric-less-than
12
+ # @see http://www.w3.org/TR/xpath-functions/#func-boolean-less-than
13
+ # @see http://www.w3.org/TR/xpath-functions/#func-dateTime-less-than
14
+ class LessThan < Compare
15
+ NAME = :<
16
+
17
+ ##
18
+ # Returns `true` if the first operand is less than the second
19
+ # operand; returns `false` otherwise.
20
+ #
21
+ # @param [RDF::Literal] left
22
+ # a literal
23
+ # @param [RDF::Literal] right
24
+ # a literal
25
+ # @return [RDF::Literal::Boolean] `true` or `false`
26
+ # @raise [TypeError] if either operand is not a literal
27
+ def apply(left, right)
28
+ super
29
+ end
30
+ end # LessThan
31
+ end # Operator
32
+ end; end # SPARQL::Algebra
@@ -0,0 +1,32 @@
1
+ module SPARQL; module Algebra
2
+ class Operator
3
+ ##
4
+ # The SPARQL relational `<=` (less than or equal) comparison operator.
5
+ #
6
+ # @example
7
+ # (<= ?x ?y)
8
+ #
9
+ # @see http://www.w3.org/TR/rdf-sparql-query/#OperatorMapping
10
+ # @see http://www.w3.org/TR/xpath-functions/#func-compare
11
+ # @see http://www.w3.org/TR/xpath-functions/#func-numeric-less-than
12
+ # @see http://www.w3.org/TR/xpath-functions/#func-boolean-less-than
13
+ # @see http://www.w3.org/TR/xpath-functions/#func-dateTime-less-than
14
+ class LessThanOrEqual < Compare
15
+ NAME = :<=
16
+
17
+ ##
18
+ # Returns `true` if the first operand is less than or equal to the
19
+ # second operand; returns `false` otherwise.
20
+ #
21
+ # @param [RDF::Literal] left
22
+ # a literal
23
+ # @param [RDF::Literal] right
24
+ # a literal
25
+ # @return [RDF::Literal::Boolean] `true` or `false`
26
+ # @raise [TypeError] if either operand is not a literal
27
+ def apply(left, right)
28
+ super
29
+ end
30
+ end # LessThanOrEqual
31
+ end # Operator
32
+ end; end # SPARQL::Algebra
@@ -0,0 +1,31 @@
1
+ module SPARQL; module Algebra
2
+ class Operator
3
+ ##
4
+ # The SPARQL numeric unary `-` (negation) operator.
5
+ #
6
+ # @example
7
+ # (- ?x)
8
+ # (minus ?x)
9
+ #
10
+ # @see http://www.w3.org/TR/xpath-functions/#func-numeric-unary-minus
11
+ class Minus < Operator::Unary
12
+ include Evaluatable
13
+
14
+ NAME = [:-, :minus]
15
+
16
+ ##
17
+ # Returns the operand with its sign reversed.
18
+ #
19
+ # @param [RDF::Literal::Numeric] numeric
20
+ # a numeric literal
21
+ # @return [RDF::Literal::Numeric]
22
+ # @raise [TypeError] if the operand is not a numeric literal
23
+ def apply(term)
24
+ case term
25
+ when RDF::Literal::Numeric then -term
26
+ else raise TypeError, "expected an RDF::Literal::Numeric, but got #{term.inspect}"
27
+ end
28
+ end
29
+ end # Minus
30
+ end # Operator
31
+ end; end # SPARQL::Algebra
@@ -0,0 +1,34 @@
1
+ module SPARQL; module Algebra
2
+ class Operator
3
+ ##
4
+ # The SPARQL numeric `multiply` operator.
5
+ #
6
+ # @example
7
+ # (* ?x ?y)
8
+ # (multiply ?x ?y)
9
+ #
10
+ # @see http://www.w3.org/TR/xpath-functions/#func-numeric-multiply
11
+ class Multiply < Operator::Binary
12
+ include Evaluatable
13
+
14
+ NAME = [:*, :multiply]
15
+
16
+ ##
17
+ # Returns the arithmetic product of the operands.
18
+ #
19
+ # @param [RDF::Literal::Numeric] left
20
+ # a numeric literal
21
+ # @param [RDF::Literal::Numeric] right
22
+ # a numeric literal
23
+ # @return [RDF::Literal::Numeric]
24
+ # @raise [TypeError] if either operand is not a numeric literal
25
+ def apply(left, right)
26
+ case
27
+ when left.is_a?(RDF::Literal::Numeric) && right.is_a?(RDF::Literal::Numeric)
28
+ left * right
29
+ else raise TypeError, "expected two RDF::Literal::Numeric operands, but got #{left.inspect} and #{right.inspect}"
30
+ end
31
+ end
32
+ end # Multiply
33
+ end # Operator
34
+ end; end # SPARQL::Algebra
@@ -0,0 +1,35 @@
1
+ module SPARQL; module Algebra
2
+ class Operator
3
+ ##
4
+ # The SPARQL logical `not` operator.
5
+ #
6
+ # @example
7
+ # (! ?x ?y)
8
+ # (not ?x ?y)
9
+ #
10
+ # @see http://www.w3.org/TR/xpath-functions/#func-not
11
+ class Not < Operator::Unary
12
+ include Evaluatable
13
+
14
+ NAME = [:not, :'!']
15
+
16
+ ##
17
+ # Returns the logical `NOT` (inverse) of the operand.
18
+ #
19
+ # Note that this operator operates on the effective boolean value
20
+ # (EBV) of its operand.
21
+ #
22
+ # @param [RDF::Literal::Boolean] operand
23
+ # the operand
24
+ # @return [RDF::Literal::Boolean] `true` or `false`
25
+ # @raise [TypeError] if the operand could not be coerced to a boolean literal
26
+ def apply(operand)
27
+ case bool = boolean(operand)
28
+ when RDF::Literal::Boolean
29
+ RDF::Literal(bool.false?)
30
+ else super
31
+ end
32
+ end
33
+ end # Not
34
+ end # Operator
35
+ end; end # SPARQL::Algebra
@@ -0,0 +1,26 @@
1
+ module SPARQL; module Algebra
2
+ class Operator
3
+ ##
4
+ # The SPARQL relational `!=` (not equal) comparison operator.
5
+ #
6
+ # @see http://www.w3.org/TR/rdf-sparql-query/#OperatorMapping
7
+ # @see http://www.w3.org/TR/rdf-sparql-query/#func-RDFterm-equal
8
+ class NotEqual < Equal
9
+ NAME = :'!='
10
+
11
+ ##
12
+ # Returns `true` if the operands are not equal; returns `false`
13
+ # otherwise.
14
+ #
15
+ # @param [RDF::Term] term1
16
+ # an RDF term
17
+ # @param [RDF::Term] term2
18
+ # an RDF term
19
+ # @return [RDF::Literal::Boolean] `true` or `false`
20
+ # @raise [TypeError] if either operand is not an RDF term
21
+ def apply(term1, term2)
22
+ RDF::Literal(super.false?)
23
+ end
24
+ end # NotEqual
25
+ end # Operator
26
+ end; end # SPARQL::Algebra
@@ -0,0 +1,65 @@
1
+ module SPARQL; module Algebra
2
+ class Operator
3
+ ##
4
+ # The SPARQL logical `or` operator.
5
+ #
6
+ # @example
7
+ # (|| ?x ?y)
8
+ # (or ?x ?y)
9
+ #
10
+ # @see http://www.w3.org/TR/rdf-sparql-query/#func-logical-or
11
+ # @see http://www.w3.org/TR/rdf-sparql-query/#evaluation
12
+ class Or < Operator::Binary
13
+ include Evaluatable
14
+
15
+ NAME = [:or, :'||']
16
+
17
+ ##
18
+ # Initializes a new operator instance.
19
+ #
20
+ # @param [RDF::Literal::Boolean] left
21
+ # the left operand
22
+ # @param [RDF::Literal::Boolean] right
23
+ # the right operand
24
+ # @param [Hash{Symbol => Object}] options
25
+ # any additional options (see {Operator#initialize})
26
+ # @raise [TypeError] if any operand is invalid
27
+ def initialize(left, right, options = {})
28
+ super
29
+ end
30
+
31
+ ##
32
+ # Returns the logical `OR` of the left operand and the right operand.
33
+ #
34
+ # Note that this operator operates on the effective boolean value
35
+ # (EBV) of its operands.
36
+ #
37
+ # @param [RDF::Query::Solution, #[]] bindings
38
+ # @return [RDF::Literal::Boolean] `true` or `false`
39
+ # @raise [TypeError] if the operands could not be coerced to a boolean literal
40
+ def evaluate(bindings = {})
41
+ begin
42
+ left = boolean(operand(0).evaluate(bindings)).true?
43
+ rescue TypeError
44
+ left = nil
45
+ end
46
+
47
+ begin
48
+ right = boolean(operand(1).evaluate(bindings)).true?
49
+ rescue TypeError
50
+ right = nil
51
+ end
52
+
53
+ # From http://www.w3.org/TR/rdf-sparql-query/#evaluation
54
+ # A logical-or that encounters an error on only one branch will return TRUE if the other branch is TRUE
55
+ # and an error if the other branch is FALSE.
56
+ case
57
+ when left.nil? && right.nil? then raise(TypeError)
58
+ when left.nil? then right ? RDF::Literal::TRUE : raise(TypeError)
59
+ when right.nil? then left ? RDF::Literal::TRUE : raise(TypeError)
60
+ else RDF::Literal(left || right)
61
+ end
62
+ end
63
+ end # Or
64
+ end # Operator
65
+ end; end # SPARQL::Algebra
@@ -0,0 +1,69 @@
1
+ module SPARQL; module Algebra
2
+ class Operator
3
+ ##
4
+ # The SPARQL GraphPattern `order` operator.
5
+ #
6
+ # @example
7
+ # (prefix ((foaf: <http://xmlns.com/foaf/0.1/>))
8
+ # (project (?name)
9
+ # (order ((asc ?name))
10
+ # (bgp (triple ?x foaf:name ?name)))))
11
+ #
12
+ # @see http://www.w3.org/TR/rdf-sparql-query/#modOrderBy
13
+ class Order < Operator::Binary
14
+ include Query
15
+
16
+ NAME = [:order]
17
+
18
+ ##
19
+ # Executes this query on the given `queryable` graph or repository.
20
+ # Orders a solution set returned by executing operand(1) using
21
+ # an array of expressions and/or variables specified in operand(0)
22
+ #
23
+ # @param [RDF::Queryable] queryable
24
+ # the graph or repository to query
25
+ # @param [Hash{Symbol => Object}] options
26
+ # any additional keyword options
27
+ # @return [RDF::Query::Solutions]
28
+ # the resulting solution sequence
29
+ # @see http://www.w3.org/TR/rdf-sparql-query/#sparqlAlgebra
30
+ def execute(queryable, options = {})
31
+ debug(options) {"Order"}
32
+ @solutions = operands.last.execute(queryable, options.merge(:depth => options[:depth].to_i + 1)).order do |a, b|
33
+ operand(0).inject(false) do |memo, op|
34
+ debug(options) {"=> #{op.inspect}"}
35
+ memo ||= begin
36
+ comp = case op
37
+ when RDF::Query::Variable
38
+ a[op.to_sym] <=> b[op.to_sym]
39
+ when Operator, Array
40
+ a_eval, b_eval = op.evaluate(a), op.evaluate(b)
41
+ if a_eval.nil?
42
+ RDF::Literal(-1)
43
+ elsif b_eval.nil?
44
+ RDF::Literal(1)
45
+ else
46
+ Operator::Compare.evaluate(a_eval, b_eval)
47
+ end
48
+ else
49
+ raise TypeError, "Unexpected order expression #{op.inspect}"
50
+ end
51
+ comp = -comp if op.is_a?(Operator::Desc)
52
+ comp == 0 ? false : comp
53
+ end
54
+ end || 0 # They compare equivalently if there are no matches
55
+ end
56
+ end
57
+
58
+ ##
59
+ # Returns an optimized version of this query.
60
+ #
61
+ # Return optimized query
62
+ #
63
+ # @return [Union, RDF::Query] `self`
64
+ def optimize
65
+ operands = operands.map(&:optimize)
66
+ end
67
+ end # Order
68
+ end # Operator
69
+ end; end # SPARQL::Algebra
@@ -0,0 +1,31 @@
1
+ module SPARQL; module Algebra
2
+ class Operator
3
+ ##
4
+ # The SPARQL numeric unary `+` operator.
5
+ #
6
+ # @example
7
+ # (+ ?x ?y)
8
+ # (plus ?x ?y)
9
+ #
10
+ # @see http://www.w3.org/TR/xpath-functions/#func-numeric-unary-plus
11
+ class Plus < Operator::Unary
12
+ include Evaluatable
13
+
14
+ NAME = [:+, :plus]
15
+
16
+ ##
17
+ # Returns the operand with its sign unchanged.
18
+ #
19
+ # @param [RDF::Literal::Numeric] numeric
20
+ # a numeric literal
21
+ # @return [RDF::Literal::Numeric]
22
+ # @raise [TypeError] if the operand is not a numeric literal
23
+ def apply(term)
24
+ case term
25
+ when RDF::Literal::Numeric then term
26
+ else raise TypeError, "expected an RDF::Literal::Numeric, but got #{term.inspect}"
27
+ end
28
+ end
29
+ end # Plus
30
+ end # Operator
31
+ end; end # SPARQL::Algebra
@@ -0,0 +1,45 @@
1
+ module SPARQL; module Algebra
2
+ class Operator
3
+ ##
4
+ # The SPARQL GraphPattern `prefix` operator.
5
+ #
6
+ # @example
7
+ # (prefix ((: <http://example/>))
8
+ # (graph ?g
9
+ # (bgp (triple ?s ?p ?o))))
10
+ #
11
+ # @see http://www.w3.org/TR/rdf-sparql-query/#QSynIRI
12
+ class Prefix < Binary
13
+ include Query
14
+
15
+ NAME = [:prefix]
16
+
17
+ ##
18
+ # Executes this query on the given `queryable` graph or repository.
19
+ # Really a pass-through, as this is a syntactic object used for providing
20
+ # context for URIs.
21
+ #
22
+ # @param [RDF::Queryable] queryable
23
+ # the graph or repository to query
24
+ # @param [Hash{Symbol => Object}] options
25
+ # any additional keyword options
26
+ # @return [RDF::Query::Solutions]
27
+ # the resulting solution sequence
28
+ # @see http://www.w3.org/TR/rdf-sparql-query/#sparqlAlgebra
29
+ def execute(queryable, options = {})
30
+ @solutions = operands.last.execute(queryable, options.merge(:depth => options[:depth].to_i + 1))
31
+ end
32
+
33
+ ##
34
+ # Returns an optimized version of this query.
35
+ #
36
+ # If optimize operands, and if the first two operands are both Queries, replace
37
+ # with the unique sum of the query elements
38
+ #
39
+ # @return [Union, RDF::Query] `self`
40
+ def optimize
41
+ operands.last.optimize
42
+ end
43
+ end # Prefix
44
+ end # Operator
45
+ end; end # SPARQL::Algebra
@@ -0,0 +1,46 @@
1
+ module SPARQL; module Algebra
2
+ class Operator
3
+ ##
4
+ # The SPARQL GraphPattern `order` operator.
5
+ #
6
+ # @example
7
+ # (select (?v)
8
+ # (project (?v)
9
+ # (filter (= ?v 2)
10
+ # (bgp (triple ?s <http://example/p> ?v)))))
11
+ #
12
+ # @see http://www.w3.org/TR/rdf-sparql-query/#modProjection
13
+ class Project < Operator::Binary
14
+ include Query
15
+
16
+ NAME = [:project]
17
+
18
+ ##
19
+ # Executes this query on the given `queryable` graph or repository.
20
+ # Reduces the result set to the variables listed in the first operand
21
+ #
22
+ # @param [RDF::Queryable] queryable
23
+ # the graph or repository to query
24
+ # @param [Hash{Symbol => Object}] options
25
+ # any additional keyword options
26
+ # @return [RDF::Query::Solutions]
27
+ # the resulting solution sequence
28
+ # @see http://www.w3.org/TR/rdf-sparql-query/#sparqlAlgebra
29
+ def execute(queryable, options = {})
30
+ @solutions = operands.last.
31
+ execute(queryable, options.merge(:depth => options[:depth].to_i + 1)).
32
+ project(*(operands.first))
33
+ end
34
+
35
+ ##
36
+ # Returns an optimized version of this query.
37
+ #
38
+ # Return optimized query
39
+ #
40
+ # @return [Union, RDF::Query] `self`
41
+ def optimize
42
+ operands = operands.map(&:optimize)
43
+ end
44
+ end # Project
45
+ end # Operator
46
+ end; end # SPARQL::Algebra