grel 0.1.1 → 0.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.
Files changed (4) hide show
  1. data/lib/grel/base.rb +33 -1
  2. data/lib/grel/ql.rb +146 -8
  3. data/lib/grel.rb +2 -1
  4. metadata +2 -2
data/lib/grel/base.rb CHANGED
@@ -148,6 +148,35 @@ module GRel
148
148
  @last_query_context.run
149
149
  end
150
150
 
151
+ # Add some rules to the database.
152
+ # The rules are expressed as a hash map where the body of the rule
153
+ # is the key and the head of the rule is the value.
154
+ # Variables in the rule are expressed as strings starting with the '?' character.
155
+ # Classes and properties are expressed as symbols as usual.
156
+ # If the rules cannot be parsed, an exception will be raised.
157
+ def rules(rules)
158
+ rules = QL.to_rules(rules)
159
+ GRel::Debugger.debug "STORING IN SCHEMA #{@schema_graph}"
160
+ GRel::Debugger.debug rules
161
+ GRel::Debugger.debug "IN"
162
+ GRel::Debugger.debug @db_name
163
+ @connection.add(@db_name, rules, @schema_graph, "application/rdf+xml")
164
+ self
165
+ end
166
+
167
+ # Removes rules from the graph.
168
+ # It accepts a hash of rules definitions that will be removed.
169
+ # It returns the current graph object.
170
+ def retract_rules(rules)
171
+ rules = QL.to_rules(rules)
172
+ GRel::Debugger.debug "REMOVING FROM SCHEMA #{@schema_graph}"
173
+ GRel::Debugger.debug rules
174
+ GRel::Debugger.debug "IN"
175
+ GRel::Debugger.debug @db_name
176
+ @connection.remove(@db_name, rules, @schema_graph, "text/turtle")
177
+ self
178
+ end
179
+
151
180
  # Defines schema meta data that will be used in the processing of queries
152
181
  # if reasoning is activated.
153
182
  # It accepts a list of definitions as an argument.
@@ -332,6 +361,7 @@ module GRel
332
361
  GRel::Debugger.debug "** OFFSET #{@last_query_context.offset}" if @last_query_context.offset
333
362
  GRel::Debugger.debug "----------------------"
334
363
  args = {:describe => true}
364
+ #args = {}
335
365
  args[:accept] = options[:accept] if options[:accept]
336
366
  args[:offset] = @last_query_context.offset if @last_query_context.offset
337
367
  args[:limit] = @last_query_context.limit if @last_query_context.limit
@@ -415,10 +445,12 @@ module GRel
415
445
 
416
446
  if(p == :@some)
417
447
  restriction = BlankId.new
418
- unfolded += [s, :@subclass, restriction]
419
448
  unfolded += [restriction, :@type, :"<http://www.w3.org/2002/07/owl#Restriction>"]
420
449
  unfolded += [restriction, :"<http://www.w3.org/2002/07/owl#onProperty>", o.first]
421
450
  unfolded += [restriction, :@some,o.last]
451
+ elsif(p == :@same_as)
452
+ p = GRel::QL.to_query(p).to_sym
453
+ unfolded += [s,p,o]
422
454
  elsif(p == :@all)
423
455
  restriction = BlankId.new
424
456
  unfolded += [s, :@subclass, restriction]
data/lib/grel/ql.rb CHANGED
@@ -1,6 +1,119 @@
1
1
  module GRel
2
2
  module QL
3
3
 
4
+ def self.to_rules(obj,context={})
5
+ if(obj.is_a?(String) && obj[0..0] == "?")
6
+ var_name = obj[1..-1]
7
+ axiom = "<swrl:Variable rdf:about=\"http://www.w3.org/2003/11/swrl##{obj[1..-1]}\"></swrl:Variable>"
8
+ context[var_name] = axiom
9
+ "http://www.w3.org/2003/11/swrl##{obj[1..-1]}"
10
+ elsif(obj.is_a?(Symbol))
11
+ "##{obj}"
12
+ elsif(obj.is_a?(Array))
13
+ if(obj.first.is_a?(Symbol))
14
+ elem = obj.first
15
+ if(elem.to_s[0] == "$")
16
+ pred = case elem
17
+ when :$lt
18
+ "<swrl:BuiltinAtom><swrl:builtin rdf:resource=\"http://www.w3.org/2003/11/swrlb#lessThan\"/><swrl:arguments ><rdf:List>ARGS</rdf:List></swrl:arguments></swrl:BuiltinAtom>"
19
+ when :$gt
20
+ "<swrl:BuiltinAtom><swrl:builtin rdf:resource=\"http://www.w3.org/2003/11/swrlb#greaterThan\"/><swrl:arguments ><rdf:List>ARGS</rdf:List></swrl:arguments></swrl:BuiltinAtom>"
21
+ when :$lte
22
+ "<swrl:BuiltinAtom><swrl:builtin rdf:resource=\"http://www.w3.org/2003/11/swrlb#lessThanOrEqual\"/><swrl:arguments ><rdf:List>ARGS</rdf:List></swrl:arguments></swrl:BuiltinAtom>"
23
+ when :$gte
24
+ "<swrl:BuiltinAtom><swrl:builtin rdf:resource=\"http://www.w3.org/2003/11/swrlb#greaterThanOrEqual\"/><swrl:arguments ><rdf:List>ARGS</rdf:List></swrl:arguments></swrl:BuiltinAtom>"
25
+ when :$eq
26
+ "<swrl:BuiltinAtom><swrl:builtin rdf:resource=\"http://www.w3.org/2003/11/swrlb#equal\"/><swrl:arguments ><rdf:List>ARGS</rdf:List></swrl:arguments></swrl:BuiltinAtom>"
27
+ when :$neq
28
+ "<swrl:BuiltinAtom><swrl:builtin rdf:resource=\"http://www.w3.org/2003/11/swrlb#notEqual\"/><swrl:arguments ><rdf:List>ARGS</rdf:List></swrl:arguments></swrl:BuiltinAtom>"
29
+ end
30
+
31
+ args = []
32
+
33
+ if(obj[1].is_a?(String) && obj[1][0] == "?")
34
+ args << "<rdf:first rdf:resource=\"#{GRel::QL.to_rules(obj[1], context)}\" />"
35
+ else
36
+ args << GRel::QL.to_rules(obj[1],context).gsub("swrl:argumentn","rdf:first")
37
+ end
38
+
39
+ if(obj[2].is_a?(String) && obj[2][0] == "?")
40
+ args << "<rdf:rest><rdf:List><rdf:first rdf:resource=\"#{GRel::QL.to_rules(obj[2],context)}\"/><rdf:rest rdf:resource=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#nil\"/></rdf:List></rdf:rest>"
41
+ else
42
+ args << "<rdf:rest><rdf:List>#{GRel::QL.to_rules(obj[2],context).gsub("swrl:argumentn","rdf:first")}<rdf:rest rdf:resource=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#nil\"/></rdf:List></rdf:rest>"
43
+ end
44
+
45
+ pred.gsub(">ARGS<",">#{args.join}<")
46
+ elsif(elem.to_s.capitalize == elem.to_s) # is a class atom
47
+ pred = "<swrl:classAtom><swrl:classPredicate rdf:resource=\"#{GRel::QL.to_rules(elem,context)}\" />"
48
+ pred += "<swrl:argument1 rdf:resource=\"#{GRel::QL.to_rules(obj[1],context)}\" />"
49
+ pred + "</swrl:classAtom>"
50
+ elsif(elem.to_s.capitalize != elem.to_s) # is a property axiom
51
+ is_data = obj[1..-1].detect{|e| !e.is_a?(String) || ( e.is_a?(String) && e[0] != "?" && e.index("@id") != 0 ) }
52
+ if(is_data) # data property
53
+ pred = "<swrl:DatavaluedPropertyAtom>"
54
+ pred += "<swrl:propertyPredicate rdf:resource=\"http://grel.org/vocabulary#{GRel::QL.to_rules(elem,context)}\"/>"
55
+ if(obj[1].is_a?(String) && (obj[1][0] == "?" || obj[1].index("@id")==0))
56
+ pred += "<swrl:argument1 rdf:resource=\"#{GRel::QL.to_rules(obj[1], context)}\" />"
57
+ else
58
+ pred += GRel::QL.to_rules(obj[1], context).gsub("argumentn","argument1")
59
+ end
60
+ if(obj[2].is_a?(String) && (obj[2][0] == "?" || obj[2].index("@id")==0))
61
+ pred += "<swrl:argument1 rdf:resource=\"#{GRel::QL.to_rules(obj[2], context)}\" />"
62
+ else
63
+ pred += GRel::QL.to_rules(obj[2], context).gsub("argumentn","argument2")
64
+ end
65
+ pred + "</swrl:DatavaluedPropertyAtom>"
66
+ else # individual property
67
+ pred = "<swrl:IndividualPropertyAtom>"
68
+ pred += "<swrl:propertyPredicate rdf:resource=\"http://grel.org/vocabulary#{GRel::QL.to_rules(elem,context)}\"/>"
69
+ pred += "<swrl:argument1 rdf:resource=\"#{GRel::QL.to_rules(obj[1],context)}\" />"
70
+ pred += "<swrl:argument2 rdf:resource=\"#{GRel::QL.to_rules(obj[2],context)}\" />"
71
+ pred + "</swrl:IndividualPropertyAtom>"
72
+ is_object = obj[1..-1].detect{|e| !e.is_a?(String) && ( e.is_a?(String) && e.index("@id") != 0 ) }
73
+ unless(is_object)
74
+ pred = "<swrl:DatavaluedPropertyAtom>"
75
+ pred += "<swrl:propertyPredicate rdf:resource=\"http://grel.org/vocabulary#{GRel::QL.to_rules(elem,context)}\"/>"
76
+ pred += "<swrl:argument1 rdf:resource=\"#{GRel::QL.to_rules(obj[1],context)}\" />"
77
+ pred += "<swrl:argument2 rdf:resource=\"#{GRel::QL.to_rules(obj[2],context)}\" />"
78
+ pred + "</swrl:DatavaluedPropertyAtom>"
79
+ end
80
+ end
81
+ else
82
+ raise Exception.new("Unkown rule axiom #{obj.inspect}")
83
+ end
84
+ elsif(obj.first.is_a?(Array))
85
+ obj.map{|ax| GRel::QL.to_rules(ax,context)}.join("")
86
+ else
87
+ raise Exception.new("Unkown rule axiom #{obj.inspect}")
88
+ end
89
+ elsif(obj.is_a?(String) && obj.index("@id")==0) # is a IRI
90
+ GRel::QL::to_id(obj).gsub("<","").gsub(">","")
91
+ elsif(obj.is_a?(String)) # is a IRI
92
+ "<swrl:argumentn rdf:datatype=\"http://www.w3.org/2001/XMLSchema#string\">#{obj}</swrl:argumentn>"
93
+ elsif(obj == true || obj == false)
94
+ "<swrl:argumentn rdf:datatype=\"http://www.w3.org/2001/XMLSchema#boolean\">#{obj}</swrl:argumentn>"
95
+ elsif(obj.is_a?(Float))
96
+ "<swrl:argumentn rdf:datatype=\"http://www.w3.org/2001/XMLSchema#float\">#{obj}</swrl:argumentn>"
97
+ elsif(obj.is_a?(Numeric))
98
+ "<swrl:argumentn rdf:datatype=\"http://www.w3.org/2001/XMLSchema#integer\">#{obj}</swrl:argumentn>"
99
+ elsif(obj.is_a?(Time))
100
+ "<swrl:argumentn rdf:datatype=\"http://www.w3.org/2001/XMLSchema#dateTime\">#{obj.iso8601}</swrl:argumentn>"
101
+ elsif(obj.is_a?(Date))
102
+ "<swrl:argumentn rdf:datatype=\"http://www.w3.org/2001/XMLSchema#dateTime\">#{Time.new(obj.to_s).iso8601}</swrl:argumentn>"
103
+ # Building the document here
104
+ elsif(obj.is_a?(Hash))
105
+ rules = obj.map do |(body,head)|
106
+ "<swrl:Imp><swrl:body rdf:parseType=\"Collection\">#{GRel::QL.to_rules(body,context)}</swrl:body ><swrl:head rdf:parseType=\"Collection\">#{GRel::QL.to_rules(head,context)}</swrl:head></swrl:Imp>"
107
+ end.join("")
108
+ doc = "<rdf:RDF xml:base=\"#{GRel::NAMESPACE}\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:owl=\"http://www.w3.org/2002/07/owl#\" xmlns:swrl=\"http://www.w3.org/2003/11/swrl#\" xmlns:ruleml=\"http://www.w3.org/2003/11/swrl\">"
109
+ doc += context.values.join("")
110
+ doc += rules
111
+ doc + "</rdf:RDF>"
112
+ else
113
+ raise Exception.new("Unkown rule axiom #{obj.inspect}")
114
+ end
115
+ end
116
+
4
117
  def self.unlink_sparql_query(ids)
5
118
  conditions = ids.map do |id|
6
119
  id = "@id(#{id})" if id && id.is_a?(String) && id.index("@id(").nil?
@@ -39,6 +152,14 @@ module GRel
39
152
  "rdfs:domain"
40
153
  elsif(obj == :@range)
41
154
  "rdfs:range"
155
+ elsif(obj == :@same_as)
156
+ "<http://www.w3.org/2002/07/owl#sameAs>"
157
+ elsif(obj == :@functional)
158
+ "<http://www.w3.org/2002/07/owl#FunctionalProperty>"
159
+ elsif(obj == :"<http://www.w3.org/2002/07/owl#FunctionalProperty>")
160
+ "<http://www.w3.org/2002/07/owl#FunctionalProperty>"
161
+ elsif(obj == :"<http://www.w3.org/2002/07/owl#sameAs>")
162
+ "<http://www.w3.org/2002/07/owl#sameAs>"
42
163
  elsif(obj == :"<http://www.w3.org/2002/07/owl#onClass>")
43
164
  "<http://www.w3.org/2002/07/owl#onClass>"
44
165
  elsif(obj == :"<http://www.w3.org/2002/07/owl#qualifiedCardinality>")
@@ -123,8 +244,8 @@ module GRel
123
244
  acum << [p,v] if v && k != :@id
124
245
  elsif(v.is_a?(Array)) # array as a property in a hash
125
246
  v.map{|o| QL.to_triples(o) }.each do |o|
126
- if(o.is_a?(Array) && o.length > 0)
127
- acum << [p, o[0][0]]
247
+ if(o.is_a?(Array) || o.respond_to?(:triples_id))
248
+ acum << [p, o.triples_id]
128
249
  triples_nested += o
129
250
  else
130
251
  acum << [p, o]
@@ -142,7 +263,9 @@ module GRel
142
263
 
143
264
  id = id || BlankId.new
144
265
 
145
- triples_acum + acum.map{|(p,o)| [id, p, o] } + triples_nested
266
+ triples_acum = triples_acum + acum.map{|(p,o)| [id, p, o] } + triples_nested
267
+ triples_acum.triples_id = id
268
+ triples_acum
146
269
  else
147
270
  if(obj.respond_to?(:to_triples))
148
271
  obj.to_triples
@@ -158,7 +281,7 @@ module GRel
158
281
  NODE = "NODE"
159
282
 
160
283
  attr_reader :last_registered_subject, :nodes, :projection, :limit, :offset, :order, :orig_query
161
- attr_accessor :triples, :optional_triples, :optional, :unions
284
+ attr_accessor :triples, :optional_triples, :optional, :unions, :top_level
162
285
 
163
286
  def initialize(graph=nil)
164
287
  @id_counter = -1
@@ -176,6 +299,7 @@ module GRel
176
299
  @offset = nil
177
300
  @orig_query = nil
178
301
  @query_keys = []
302
+ @top_level = true
179
303
  end
180
304
 
181
305
  def register_query(query)
@@ -253,7 +377,6 @@ module GRel
253
377
  end
254
378
 
255
379
  def to_sparql_describe(preamble=true)
256
-
257
380
  bgps = @triples.map{|t|
258
381
  if(t.is_a?(Filter))
259
382
  t.acum
@@ -607,15 +730,24 @@ module GRel
607
730
  end
608
731
 
609
732
  def parse_property(k)
610
- QL.to_query(k, context)
733
+ if(k.is_a?(String))
734
+ k.gsub(":@type","<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>").
735
+ gsub(":$inv_","^:")
736
+ else
737
+ QL.to_query(k, context)
738
+ end
611
739
  end
612
740
 
613
741
  end # end of BGP
614
742
 
615
- def self.to_query(obj,context=QL::QueryContext.new, inverse=false)
743
+ def self.to_query(obj, context=QL::QueryContext.new, inverse=false)
744
+ top_level = context.top_level
745
+ context.top_level = false
616
746
  if(obj.is_a?(Symbol))
617
747
  if(obj == :@type)
618
748
  "rdf:type"
749
+ elsif(obj == :@same_as)
750
+ "<http://www.w3.org/2002/07/owl#sameAs>"
619
751
  elsif(obj.to_s.index("$inv_"))
620
752
  ":#{obj.to_s.split("$inv_").last}"
621
753
  elsif(obj.to_s == "_")
@@ -648,7 +780,13 @@ module GRel
648
780
  filter
649
781
  else
650
782
  bgp = BGP.new(obj,context,inverse)
651
- context.append(bgp.to_query)
783
+ next_triples = bgp.to_query
784
+ # avoid patterns [?s1 ?p1 ?o1] where ?s1 is already linked in ?s0 ?p0 ?s1
785
+ # they fail for SWRL rules in DESCRIBE queries
786
+ unless(top_level == false && next_triples.length == 1 &&
787
+ next_triples.first.reject{|c| c.index("?")==0 && c.index("_mg_") }.empty?)
788
+ context.append(next_triples)
789
+ end
652
790
  context
653
791
  end
654
792
  else
data/lib/grel.rb CHANGED
@@ -4,10 +4,11 @@ require 'uri'
4
4
  require 'securerandom'
5
5
 
6
6
  class Array
7
+ attr_accessor :triples_id
7
8
  # When using an array of arrays to hold list of triples,
8
9
  # returns the first triple subject.
9
10
  def triples_id
10
- self.first.first
11
+ @triples_id || self.first.first
11
12
  end
12
13
  end
13
14
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-25 00:00:00.000000000 Z
12
+ date: 2013-04-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: stardog-rb