grel 0.1.1 → 0.1.2

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