sparql 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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