rdf-isomorphic 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
@@ -1,5 +1,6 @@
1
1
  require 'digest/sha1'
2
2
  require 'rdf'
3
+ require 'rdf/ntriples'
3
4
 
4
5
 
5
6
  module RDF
@@ -75,7 +76,6 @@ module RDF
75
76
  # @private
76
77
  def build_bijection_to(anon_stmts, nodes, other_anon_stmts, other_nodes, these_grounded_hashes = {}, other_grounded_hashes = {})
77
78
 
78
-
79
79
  # Create a hash signature of every node, based on the signature of
80
80
  # statements it exists in.
81
81
  # We also save hashes of nodes that cannot be reliably known; we will use
@@ -85,20 +85,31 @@ module RDF
85
85
  these_hashes, these_ungrounded_hashes = RDF::Isomorphic.hash_nodes(anon_stmts, nodes, these_grounded_hashes)
86
86
  other_hashes, other_ungrounded_hashes = RDF::Isomorphic.hash_nodes(other_anon_stmts, other_nodes, other_grounded_hashes)
87
87
 
88
+ # Grounded hashes are built at the same rate between the two graphs (if
89
+ # they are isomorphic). If there exists a grounded node in one that is
90
+ # not in the other, we can just return. Ungrounded nodes might still
91
+ # conflict, so we don't check them. This is a little bit messy in the
92
+ # middle of the method, and probably slows down isomorphic checks, but
93
+ # prevents almost-isomorphic cases from getting nutty.
94
+ return nil if these_hashes.values.any? { |hash|
95
+ !(other_hashes.values.member?(hash)) }
96
+ return nil if other_hashes.values.any? { |hash| !(these_hashes.values.member?(hash)) }
88
97
 
89
98
  # Using the created hashes, map nodes to other_nodes
99
+ # Ungrounded hashes will also be equal, but we keep the distinction
100
+ # around for when we recurse later (we only recurse on ungrounded nodes)
90
101
  bijection = {}
91
102
  nodes.each do | node |
92
- other_node, other_hash = other_hashes.find do | other_node, other_hash |
103
+ other_node, other_hash = other_ungrounded_hashes.find do | other_node, other_hash |
93
104
  # we need to use eql?, as coincedentally-named bnode identifiers are == in rdf.rb
94
- these_hashes[node].eql? other_hash
105
+ these_ungrounded_hashes[node].eql? other_hash
95
106
  end
96
107
  next unless other_node
97
108
  bijection[node] = other_node
98
-
99
- # we need to delete , as we don't want two nodes with the same hash
100
- # to be mapped to the same other_node.
101
- other_hashes.delete other_node
109
+
110
+ # Deletion is required to keep counts even; two nodes with identical
111
+ # signatures can biject to each other at random.
112
+ other_ungrounded_hashes.delete other_node
102
113
  end
103
114
 
104
115
  # bijection is now a mapping of nodes to other_nodes. If all are
@@ -166,17 +177,26 @@ module RDF
166
177
  # grounded, other nodes can then use it to decide their own state of
167
178
  # grounded.
168
179
  while hash_needed
169
- hash_needed = false
180
+ starting_grounded_nodes = hashes.size
170
181
  nodes.each do | node |
171
182
  unless hashes.member? node
172
183
  grounded, hash = node_hash_for(node, statements, hashes)
173
184
  if grounded
174
- hash_needed = true
175
185
  hashes[node] = hash
176
186
  end
177
187
  ungrounded_hashes[node] = hash
178
188
  end
179
189
  end
190
+ # after going over the list, any nodes with a unique hash can be marked
191
+ # as grounded, even if we have not tied them back to a root yet.
192
+ uniques = {}
193
+ ungrounded_hashes.each do |node, hash|
194
+ uniques[hash] = uniques[hash].is_a?(RDF::Node) ? false : node
195
+ end
196
+ uniques.each do |hash, node|
197
+ hashes[node] = hash unless node == false
198
+ end
199
+ hash_needed = starting_grounded_nodes != hashes.size
180
200
  end
181
201
  [hashes,ungrounded_hashes]
182
202
  end
@@ -245,6 +265,10 @@ module RDF
245
265
  hashes[node]
246
266
  when node.node?
247
267
  "a blank node"
268
+ # RDF.rb auto-boxing magic makes some literals the same when they
269
+ # should not be; the ntriples serializer will take care of us
270
+ when node.literal?
271
+ node.class.name + RDF::NTriples.serialize(node)
248
272
  else
249
273
  node.to_s
250
274
  end
@@ -1,7 +1,7 @@
1
1
  module RDF::Isomorphic
2
2
  module VERSION
3
3
  MAJOR = 0
4
- MINOR = 2
4
+ MINOR = 3
5
5
  TINY = 0
6
6
  EXTRA = nil
7
7
 
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 2
7
+ - 3
8
8
  - 0
9
- version: 0.2.0
9
+ version: 0.3.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Ben Lavender
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-06-18 00:00:00 -05:00
18
+ date: 2010-10-26 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency